问题描述
我正在使用 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}
我回顾一下我所做的所有动作:
- 在给定提供者 google-oauth2 重定向 URL 的情况下,向后端生成前端请求。通过此操作,生成的 url 还会将状态密钥存储在具有特定值 (google-oauth2_state) 的会话中。
- 前端接收 url 并重定向到 google auth 页面。
- 使用 google 进行身份验证,并使用 url 上的 state 和 code 参数重定向回前端。
- 前端获取数据表单 url 并将数据发布到后端以验证收到的状态是否等于点 (1) 上生成的状态。
由于某些原因,状态代码没有保留......任何想法和帮助将不胜感激。
谢谢大家。
解决方法
没有必要的详细信息,我只能说出两个可能的原因:
- 您使用不正确的
session
操作覆盖了后端(或者用户在身份验证完成之前已注销)。 - 前端使用了错误的
state
参数
您可以在没有前端的情况下测试社交登录,假设您尝试使用 Google 登录:
- 在浏览器中输入社交登录 URL,例如
domain.com:8000/login/google-oauth2/
- 授权
- 查看页面是否正确重定向到您的默认登录页面
如果是,那么您可能需要检查您的前端代码,如果不是,则检查您的后端代码。
最后,如果您对潜在风险不那么敏感,您还可以按如下方式覆盖 GoogleOAuth2
类以禁用状态检查:
from social_core.backends import google
class GoogleOAuth2(google.GoogleOAuth2):
STATE_PARAMETER = False
,
我认为您可能需要对第 3 步和第 4 步中的授权流程进行一些更改。
3.使用google进行身份验证,并通过url上的状态和代码参数重定向回前端。
4.前端获取数据表单url并将数据发布到后端以验证接收到的状态等于点(1)上生成的状态。
也许你应该在谷歌授权后重定向回服务器端。
然后在服务器端进行检查!验证状态和代码(也许可以做更多的事情)。
然后让服务器重定向到您之前想要访问的前端站点。
出于某种原因,直接重定向到前端会错过参数.. :-)
,好的,所以这是您使用社交身份验证时的常见问题。我遇到了很多次同样的问题。
流程:
-
向
http://127.0.0.1:8000/auth/o/google-oauth2/?redirect_uri=http://localhost:3000/
发出请求(示例) -
你会得到一个
authorization_url
。如果您注意到此 authorization_url 中存在一个状态。这是“服务器端的状态”。 -
现在你需要点击authorization_url链接。然后你会得到谷歌认证页面。之后你将被重定向到带有状态和代码的重定向url。记住这个状态应该和服务器端的状态一样。(2)
-
将帖子请求发送到
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=''
这样你就会得到相同的状态。