You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过ngrok在请求中包含Django CSRF令牌?

我刚好折腾过局域网Django应用集成Facebook Login的场景,给你梳理一下关键实现步骤和踩过的坑:

局域网Django + Facebook Login 实现指南

一、先搞定Facebook回调地址的限制(ngrok配置)

Facebook要求回调地址必须是localhost或公网可访问的域名,局域网服务刚好卡在这里,用ngrok就能完美解决:

  • 启动ngrok映射你的本地Django端口,比如本地跑8000端口,执行命令:ngrok http 8000
  • 复制ngrok生成的公网域名(比如https://abc-12-34-56-78.ngrok.io),登录Facebook开发者后台,找到你的App→「产品」→「Facebook登录」→「设置」,把这个域名加上回调路径(比如https://abc-12-34-56-78.ngrok.io/facebook/callback)添加到「有效的OAuth跳转URI」列表里。注意:每次重启ngrok都会换域名,要记得更新这个配置,嫌麻烦可以买ngrok付费版用固定域名。

二、Django端的基础认证配置

我个人推荐用django-allauth来做社交认证,比自己手写OAuth2流程省心太多:

  • 先安装依赖:pip install django-allauth
  • 在settings.py里添加配置:
    INSTALLED_APPS = [
        # 你的其他Django应用
        'allauth',
        'allauth.account',
        'allauth.socialaccount',
        'allauth.socialaccount.providers.facebook',
    ]
    
    # 配置认证后端
    AUTHENTICATION_BACKENDS = [
        'django.contrib.auth.backends.ModelBackend',
        'allauth.account.auth_backends.AuthenticationBackend',
    ]
    
    # Facebook Provider配置
    SOCIALACCOUNT_PROVIDERS = {
        'facebook': {
            'APP': {
                'client_id': '你的Facebook App ID',
                'secret': '你的Facebook App Secret',
                'key': ''
            },
            'SCOPE': ['email', 'public_profile'],  # 要获取的用户权限
            'FIELDS': ['id', 'email', 'name', 'picture'],  # 要拉取的用户字段
            'VERSION': 'v18.0'  # 用最新的Graph API版本
        }
    }
    
  • 把allauth的路由加到项目的urls.py:
    urlpatterns = [
        # 其他路由
        path('accounts/', include('allauth.urls')),
    ]
    

三、AJAX提交用户数据到本地视图的关键细节

你提到登录后用AJAX把用户数据POST到/fb_login存库,这里有几个必须注意的点:

  • 一定要带CSRF令牌:Django默认会拦截没有CSRF令牌的POST请求,前端可以这么处理:
    // 从模板的csrf_token标签里拿令牌
    const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
    // 发送AJAX请求
    fetch('/fb_login', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRFToken': csrftoken
        },
        body: JSON.stringify({
            facebook_id: response.authResponse.userID,
            name: response.name,
            email: response.email,
            access_token: response.authResponse.accessToken
        })
    })
    
  • 后端必须验证access_token的合法性:前端传的数据可能被篡改,所以一定要调用Facebook的调试接口校验token有效性,比如:
    import requests
    from django.conf import settings
    
    def validate_fb_token(access_token):
        app_id = settings.SOCIALACCOUNT_PROVIDERS['facebook']['APP']['client_id']
        app_secret = settings.SOCIALACCOUNT_PROVIDERS['facebook']['APP']['secret']
        debug_url = f"https://graph.facebook.com/debug_token?input_token={access_token}&access_token={app_id}|{app_secret}"
        response = requests.get(debug_url)
        return response.json().get('data', {}).get('is_valid', False)
    
  • 处理用户登录状态:验证通过后,要么创建新用户,要么更新已有用户,然后用Django的login()方法设置用户登录状态:
    from django.http import JsonResponse
    from django.contrib.auth import login
    from django.contrib.auth.models import User
    import json
    
    def fb_login(request):
        if request.method != 'POST':
            return JsonResponse({'status': 'error', 'msg': '仅支持POST请求'})
        
        data = json.loads(request.body)
        fb_id = data.get('facebook_id')
        access_token = data.get('access_token')
        
        # 先验证token
        if not validate_fb_token(access_token):
            return JsonResponse({'status': 'error', 'msg': '无效的Facebook令牌'})
        
        # 查找或创建用户
        user, created = User.objects.get_or_create(username=fb_id, defaults={
            'first_name': data.get('name'),
            'email': data.get('email')
        })
        # 设置登录状态
        login(request, user)
        return JsonResponse({'status': 'success', 'msg': '登录成功'})
    

四、局域网环境的额外注意事项

  • 确保你的Django服务绑定的是0.0.0.0而不是127.0.0.1,这样局域网内的设备才能访问,启动命令用:python manage.py runserver 0.0.0.0:8000
  • 测试的时候先用ngrok的公网域名打开你的Django页面,确认能正常访问,再测试Facebook登录流程,避免因为网络问题导致回调失败。

内容的提问来源于stack exchange,提问作者phepp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:03:49