获取csrftoken
一个一般的登录接口是这样写的
from django.contrib.auth import login, authenticate
@api_view(['POST'])
@validate_request(LoginSerializer)
def login_view(request, data):
user = authenticate(**data)
if user is None:
return response_util(ErrorCode.PASSWORD_ERROR)
login(request, user)
return response_util(ErrorCode.SUCCESS, CustomUserSerializer(user).data)account/views.py
当前端或一些接口调用工具(Postman、Apifox)请求该接口并登录成功后,Response Cookie中会带有一个 Cookie 名为csrftoken的字段。前端应该将其存储起来,接口调用工具可以使用接口后置操作提取该变量。
我不太懂前端,有些和我前端对接的同学,会要求我设置
SESSION_COOKIE_HTTPONLY = False settings.py
否则他们拿不到 Cookie,也就拿不到 csrftoken。但我查了一下,Session Cookie 和 CSRF Cookie 是两个不同的 Cookie,csrftoken 是可以直接从document.cookie中获取到的。总之如果前端拿不到 Cookie,你可以尝试设置一下这个字段,请注意它会带来跨站脚本攻击(XSS)风险。
传入并校验csrftoken
在请求其他接口时,应在请求的 Header 中添加名为X-CSRFToken的参数,其值为上一步获取的csrftoken
Django 后端在接受到该请求后,会自动校验该 token。若通过则request.user.is_authenticated为true,可以通过这种方法,判断用户是否登录。
例如下面是一个校验用户已登录的修饰器,可以写在任何需要登录的接口前
from functools import wraps
def login_required(view_func):
@wraps(view_func)
def wrapper(request, *args, **kwargs):
if not request.user.is_authenticated:
return response_util(ErrorCode.NOT_LOGGED_IN)
return view_func(request, *args, **kwargs)
return wrapperlogin_required.py
配置前端部署地址
无论前端是部署在某个服务器上还是你的同事在本地电脑测试,都需要将对应 IP 和端口配置在 Django 项目中。这项要求似乎是最近(24-25年) Django 某次更新后新增的。配置方法如下
CSRF_TRUSTED_ORIGINS = [
'http://localhost:5173',
'http://127.0.0.1:5173',
'http://10.61.1.201:5173',
'http://10.70.251.43:9167',
'http://10.70.251.43:9163',
]settings.py