【问题标题】:How to pass in the user in the request for Auth0? (React Frontend and Django Backend)如何在 Auth0 的请求中传入用户? (反应前端和 Django 后端)
【发布时间】:2021-11-02 00:14:34
【问题描述】:

我正在创建一个 Web 应用程序并尝试使用 Auth0 进行用户身份验证。 我想保护一些用户必须登录才能成功访问端点的端点。

我按照这篇关于使用 Auth0 设置 Django 的教程进行了操作,结果非常完美。

(https://auth0.com/docs/quickstart/webapp/django/01-login)

但是,尽管我希望能够从前端 (React) 登录,以便能够访问我的 Django 后端上的安全端点。

这就是我正在测试的端点所拥有的。

views.py

from django.http import JsonResponse

def test(request):
    user = request.user
    if user.is_authenticated:
        return JsonResponse({ 'outcome': 'success'}) 
    else:
        return JsonResponse({ 'outcome': 'failure'})

此端点在我的urls.py 中称为path('test/', views.test),

当我使用模板登录然后尝试访问端点时,它可以正常工作。

templates/index.html

<div class="login-box auth0-box before">
    <img src="https://i.cloudup.com/StzWWrY34s.png" />
    <h3>Auth0 Example</h3>
    <p>Zero friction identity infrastructure, built for developers</p>
    <a class="btn btn-primary btn-lg btn-login btn-block" href="/login/auth0">Log In</a>
</div>

但是,问题是当我尝试通过我的 React 前端登录时。我似乎无法让 JsonResponse 成为“成功”并继续获得“失败”。

fetch('test/')
    .then(response => response.json())
    .then(data => console.log(data));

我可以从后端看到,我们必须通过request.user 获取用户,然后通过user.is_authenticated 进行检查。

但是,在我的 fetch 请求中我没有这样做。

所以我的问题是如何将用户传递到我的获取请求中?

非常感谢!

编辑:

前端代码


const LoginSignupBtn = () => {
  const classes = useStyles();
  const [popupState, updatePopupState] = useState('closed')

  const displayName = useSelector(selectDisplayName)
  const dispatch = useDispatch()

  const redirectURL = window.location.origin + '/authorize'

  useEffect(() => {
    // signup configuration
    signupLock = new Auth0LockPasswordless(
      'clientID', // clientId
      'domainID', // domain
      { // signup box options
        container: 'signup-popup',
        language: 'en',
        allowedConnections: ['email'],
        passwordlessMethod: 'code',
        allowSignUp: true,
        allowLogin: true,
        initialScreen: 'signup',
        sso: false,
        closable: true,
        auth: {
          redirectUrl: redirectURL, 
          responseType: 'token',
          params: {
            scope: 'openid email'               
          }          
        },
        theme: {
          logo: '',
          primaryColor: '#ed6641',
        },
        languageDictionary: {
          // Lang Customization: https://github.com/auth0/lock/blob/master/src/i18n/en.js
          emailInputPlaceholder: 'Your Email',
          title : 'Sign up',
          passwordlessEmailInstructions: 'Enter your email to sign up',
          passwordlessEmailCodeInstructions: 'An email with the code has been sent to %s.',
          signUpTerms: '',
          codeInputPlaceholder: 'your code ####',
          submitLabel: 'Sign up',
          resendCodeAction: "Didn't get the code?",
        },
        additionalSignUpFields: [{
          type: 'text',
          name: 'Display Name',
          placeholder: 'A display name we can use for you'
        }]
      }
    );
    // check if user is logged in
    signupLock.checkSession({}, function(err, authResult) {
      // handle error or new tokens
      const token = authResult?.accessToken

      if (token) {
        signupLock.getUserInfo(token, function(error, profile) {
            if (!error) {
              // Setting the display name in redux state
              dispatch(changeDisplayName(profile.email))
            } else {
              console.log('info err ' + error);
            }
        });      
      }
    });
  }, [])

  const signupPopup = () => {
    if (popupState === 'closed') {
      signupLock.show()
      updatePopupState('signup')
    } else {
      signupLock.hide()
      updatePopupState('closed')
    }
  }

  const loginPopup = () => {

  }

  const logout = () => {
    const logoutRedirect = window.location.origin + '/authorize'
    signupLock.logout({
      returnTo: logoutRedirect
    })
  }

  // auth checks for testing only
  const accCheck = () => {
    const info = signupLock.checkSession({}, function(err, authResult) {
      // handle error or new tokens
      const token = authResult?.accessToken
      if (token) {
        console.log(authResult)
        signupLock.getUserInfo(token, function(error, profile) {
          console.log(profile)
          if (!error) {
            console.log(profile.email);
          } else {
            console.log('info err ' + error);
          }
        });
      } else {
        console.log('sesh err ' + err);
      }
    });
  }

  const testCheck = () => {
    fetch('test/')
    .then(response => response.json())
    .then(data => console.log(data));
  }

  return (
    <>
      <div className={classes.SignupLoginWrap}>
        {displayName ? (
          <AccountDropdown lock={signupLock}/>
        ) : (
          <>
            <button className={classes.SignupBtn + ' border'} onClick={signupPopup}>Sign up</button>
            <button className={classes.SignupBtn + ' border'} onClick={loginPopup}>Login</button>            
          </>
        )}
        <button onClick={accCheck}>Acc Check</button>
        <button onClick={testCheck}>Test Check</button>
      </div>
      <div id='signup-popup' className={classes.signupPopup}></div>
    </>
  )
}

【问题讨论】:

  • 您的 React 应用如何将用户名和密码发送到 Django 后端?
  • 您好,我意识到我没有将用户信息从 React 应用程序发送到 Django 后端。但我一直在做这样的事情。我可以得到 checkSession 信息。我应该将该信息传递给 Django 后端以通过身份验证吗?

标签: reactjs django auth0 python-social-auth django-socialauth


【解决方案1】:

您似乎在这里遗漏了一些内容。让我解释一下整体方法,然后就您需要更改哪些内容以使其正常工作提出一些建议。

首先,当您保护服务器上的资源(在这种情况下为 Django 代码)时,前端(在您的情况下为 React)需要采取两个步骤来访问这些资源:

  1. 对用户进行身份验证。
  2. 为每个请求授权该用户。

有很多方法可以处理每个步骤。对于身份验证,您可以发送用户名和密码。在您的情况下,Auth0 似乎会向用户电子邮件发送一个代码,然后他们必须输入该代码。

在我熟悉的身份验证方案中,此步骤会创建一个标识已通过身份验证的用户的令牌。然后,您必须在每个请求中发送此令牌以授权该特定请求。

我认为你错过了最后一部分,因为你只是在做fetch('/test')。您需要添加此内容才能授权用户使用您的端点。有很多方法可以做到这一点。根据我的经验,最常见的是请求中的 Authorization 标头。

【讨论】:

  • 您好,感谢您抽出宝贵时间回答我的问题。所以我检查了,在 Auth0 对用户进行身份验证后,它返回一个访问令牌。我需要将此访问令牌传递到获取请求中,并且我的后端需要使用此令牌吗?我了解如何通过 Authorization 标头添加令牌,但是为来自 Django 端的每个请求授权该用户?
  • @TonyHoanTrinh React 需要通过fetch() 随每个请求发送令牌。然后 Django 将检查令牌并确保其正确并授权访问。
猜你喜欢
  • 2017-05-16
  • 1970-01-01
  • 2019-07-19
  • 2020-03-11
  • 2017-11-03
  • 2018-11-09
  • 1970-01-01
  • 1970-01-01
  • 2020-06-21
相关资源
最近更新 更多