Django、Djoser 社交身份验证:在服务器端会话数据中找不到状态。状态代码 400

Luc*_*caT 11 django django-socialauth django-rest-framework reactjs djoser

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

此时,我将这些参数发布到后端。后端尝试使用以下代码验证状态检查会话存储中是否存在状态密钥(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
Run Code Online (Sandbox Code Playgroud)

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

{"error":["State could not be found in server-side session data."],"status_code":400}
Run Code Online (Sandbox Code Playgroud)

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

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

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

谢谢大家。

YKL*_*YKL 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
Run Code Online (Sandbox Code Playgroud)