如何在Python Django中处理Google Sign-In的CSRF错误?
问题原因
你遇到的CSRF报错是因为Google Sign-In的redirect模式下,Google服务端会主动发起POST请求回调到你配置的data-login_uri地址,Django默认对所有POST请求强制校验CSRF令牌,而Google的请求无法携带你站点生成的CSRF令牌,因此直接被Django的CSRF中间件拦截。
解决步骤
1. 拆分登录视图,单独处理Google回调
不要将普通Django账号登录和Google登录回调共用同一个视图,单独新建一个视图专门处理Google的登录回调请求。
2. 给Google回调视图添加CSRF豁免
引入Django自带的CSRF豁免装饰器,跳过该视图的CSRF校验:
# 导入依赖 from django.views.decorators.csrf import csrf_exempt from django.shortcuts import redirect from django.contrib.auth import login, get_user_model from google.oauth2 import id_token from google.auth.transport import requests User = get_user_model() # 函数视图直接加装饰器 @csrf_exempt def google_login_callback(request): if request.method != "POST": return redirect("login") # 取Google返回的凭证 token = request.POST.get("credential") try: # 验证ID Token,替换为你自己的Google Client ID idinfo = id_token.verify_oauth2_token(token, requests.Request(), "你的Google Cloud Client ID") # 取用户信息 email = idinfo["email"] name = idinfo.get("name", "") # 处理Django侧登录逻辑 user, created = User.objects.get_or_create(username=email, defaults={"email": email, "first_name": name}) login(request, user) return redirect("login_success") except ValueError: # 凭证无效,跳转回登录页 return redirect("login") # 如果是类视图,使用method_decorator # from django.utils.decorators import method_decorator # @method_decorator(csrf_exempt, name='dispatch') # class GoogleLoginCallback(View): # def post(self, request): # # 同上处理逻辑
提前安装依赖:pip install google-auth,这个库完全兼容Python3,不需要用官方示例里的webapp2。
3. 修改HTML中的Google登录配置
把data-login_uri的值替换为你刚才新建的Google回调视图的对应URL即可,其他GSI配置无需改动。
额外注意点
你现有HTML底部引用Cookies.get('csrftoken')的代码依赖js.cookie.js,如果要正常运行需要先引入该库,不过这个问题不影响当前的Google登录报错修复。
内容的提问来源于stack exchange,提问作者Erik
相关产品推荐
相关产品推荐

