8

我正在用 django 实现一个身份验证系统并做出反应。这两个应用程序分别运行在 8000、3000 端口上。我已经使用 Djoser 包实现了身份验证系统。这个包使用了一些依赖项 social_core 和 social_django。一切似乎都配置好了。我单击登录 google 按钮...我被重定向到 google 登录页面,然后返回到端口 3000 上的前端反应应用程序,并带有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

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

{"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 上的状态代码参数重定向回前端。
  4. 前端获取数据形式的url,将数据post到后端,验证接收到的状态是否与点(1)上生成的状态相同。

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

谢谢大家。

4

4 回答 4

2

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

流量

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

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

  3. 现在您需要单击authorization_url 链接。然后您将获得google auth 页面。之后您将被重定向到带有状态和代码的重定向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=''因此您将获得相同的状态。

于 2021-06-23T10:02:09.770 回答
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
于 2021-04-30T00:35:50.197 回答
0

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

3. 使用 google 进行身份验证,并在 url 上使用状态和代码参数重定向回前端。
4.前端获取数据表单url,将数据post到后端,验证接收到的状态与点(1)上生成的状态相同。

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

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

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

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

于 2021-04-30T03:40:31.033 回答
0

允许 Axios 在前端维护会话

import axios from "axios";
axios.defaults.withCredentials = true;

axios.get("url")
.then(response => { 
   console.log(response) 
})
.catch(error => {
    console.log(error);
});

axios.defaults.withCredentials = true;

CORS_ORIGIN_ALLOW_ALL = 真

CORS_ALLOW_CREDENTIALS = 真

于 2021-10-29T15:52:42.287 回答