Django, Djoser social auth:在服务器端会话数据中找不到状态状态代码 400

问题描述

我正在使用 django 和 react 实现身份验证系统。这两个应用程序分别运行在端口 8000、3000 上。我已经使用 Djoser 包实现了身份验证系统。这个包使用了一些依赖项 social_core 和 social_django。一切似乎都配置好了。我点击登录谷歌按钮......我被重定向到谷歌登录页面,然后返回到我的前端反应应用程序在端口 3000 与状态代码网址上的参数。

此时我将这些参数发布到后端。后端尝试使用来自 (social_core/backends/oauth.py)

的以下代码来验证状态,检查状态密钥是否存在于会话存储中
def validate_state(self):
        """Validate state value. Raises exception on error,returns state
        value if valid."""
        if not self.STATE_ParaMETER and not self.REDIRECT_STATE:
            return None
        state = self.get_session_state()
        request_state = self.get_request_state()
        if not request_state:
            raise AuthMissingParameter(self,'state')
        elif not state:
            raise AuthStateMissing(self,'state')
        elif not constant_time_compare(request_state,state):
            raise AuthStateForbidden(self)
        else:
            return state

此时由于某些原因状态会话密钥不存在..并且我收到一条错误消息,指出在会话数据中找不到状态(下面的错误

{"error":["State Could not be found in server-side session data."],"status_code":400}

我回顾一下我所做的所有动作:

  1. 在给定提供者 google-oauth2 重定向 URL 的情况下,向后端生成前端请求。通过此操作,生成的 url 还会将状态密钥存储在具有特定值 (google-oauth2_state) 的会话中。
  2. 前端接收 url 并重定向到 google auth 页面
  3. 使用 google 进行身份验证,并使用 url 上的 statecode 参数重定向回前端。
  4. 前端获取数据表单 url 并将数据发布到后端以验证收到的状态是否等于点 (1) 上生成的状态。

由于某些原因,状态代码没有保留......任何想法和帮助将不胜感激。

谢谢大家。

解决方法

没有必要的详细信息,我只能说出两个可能的原因:

  1. 您使用不正确的 session 操作覆盖了后端(或者用户在身份验证完成之前已注销)。
  2. 前端使用了错误的 state 参数

您可以在没有前端的情况下测试社交登录,假设您尝试使用 Google 登录:

  1. 在浏览器中输入社交登录 URL,例如 domain.com:8000/login/google-oauth2/
  2. 授权
  3. 查看页面是否正确重定向到您的默认登录页面

如果是,那么您可能需要检查您的前端代码,如果不是,则检查您的后端代码。

最后,如果您对潜在风险不那么敏感,您还可以按如下方式覆盖 GoogleOAuth2 类以禁用状态检查:

from social_core.backends import google

class GoogleOAuth2(google.GoogleOAuth2):
    STATE_PARAMETER = False
,

我认为您可能需要对第 3 步和第 4 步中的授权流程进行一些更改。

3.使用google进行身份验证,并通过url上的状态和代码参数重定向回前端。
4.前端获取数据表单url并将数据发布到后端以验证接收到的状态等于点(1)上生成的状态。

也许你应该在谷歌授权后重定向回服务器端。

然后在服务器端进行检查!验证状态和代码(也许可以做更多的事情)。

然后让服务器重定向到您之前想要访问的前端站点。

出于某种原因,直接重定向到前端会错过参数.. :-)

,

好的,所以这是您使用社交身份验证时的常见问题。我遇到了很多次同样的问题。

流程

  1. http://127.0.0.1:8000/auth/o/google-oauth2/?redirect_uri=http://localhost:3000/ 发出请求(示例)

  2. 你会得到一个 authorization_url。如果您注意到此 authorization_url 中存在一个状态。这是“服务器端的状态”。

  3. 现在你需要点击authorization_url链接。然后你会得到谷歌认证页面。之后你将被重定向到带有状态和代码的重定向url。记住这个状态应该和服务器端的状态一样。(2)

  4. 将帖子请求发送到 http://127.0.0.1:8000/auth/o/google-oauth2/?state=''&code=''。 如果您的状态不同,那么您会遇到一些问题。

每次要登录时,都需要向http://127.0.0.1:8000/auth/o/google-oauth2/?redirect_uri=http://localhost:3000/发出请求 然后到 http://127.0.0.1:8000/auth/o/google-oauth2/?state=''&code='' 这样你就会得到相同的状态。