问题排查
这是报错
- setting文件中是否关闭了 csrf
如果只是django的话,就会生效,但是如果你不幸运用了drf,那么还得往下看 - 因为Drf默认使用了如下配置
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
]
}
其中SessionAuthentication是会进行csrf token校验的,所以仍然会报错
- 解决办法如下
1、投机取巧的方法
对于登录页面有必要这样做,因为再登录的时候,并没有获取到csrf token
from rest_framework.authentication import SessionAuthentication
# 重写一个认证的类
class UnsafeSessionAuthentication(SessionAuthentication):
# 什么也不做
def enforce_csrf(self, *args, **kwargs):
"""
Bypass the CSRF checks altogether
"""
pass
class UserViewSet(viewsets.ViewSet):
# 让你的视图使用重写的认证类
queryset = User.objects.all()
authentication_classes = (UnsafeSessionAuthentication,)
2、使用其他认证方法
# 改setting.py文件
# 改成你认为比较合适的认证方法,官方提供的还有 BasicAuthentication TokenAuthentication RemoteUserAuthentication Custom authentication(自定义token)
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
]
}
3、除登录页面以外的页面,可以这么做
# 打开csrf
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
前端页面,向后端请求的时候,添加x-csrftoken头部,我用的是vue + axios + ts,示例代码如下:
// 获取cookie的方法
function getCookie(name:string) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
// axios请求拦截器
instance.interceptors.request.use(
(config: AxiosRequestConfig) => {
// 添加csrf token
config.headers['X-CSRFtoken'] = getCookie('csrftoken')}
)
)
// 把浏览器关于本站的所有cookie清除掉,刷新进行重试
# drf 认证的官网链接
https://www.django-rest-framework.org/api-guide/authentication/#basicauthentication