我的设置(本地)如下:
为了使其能够正常工作,我添加了以下内容:
ALLOWED_HOSTS = [
...
'localhost',
'localhost:8000',
'localhost:8080',
]
INSTALLED_APPS = [
...
'rest_framework',
'corsheaders',
]
MIDDLEWARE = [
...
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]
CORS_ORIGIN_WHITELIST = (
'localhost:8080',
'localhost:8000',
)
CORS_ALLOW_CREDENTIALS = True
from corsheaders.defaults import default_headers
CORS_ALLOW_HEADERS = default_headers + (
'credentials',
)
我的API函数之一:
@ensure_csrf_cookie
def try_login(request):
# this is just to get the initial CSRF token:
if request.method == "GET" or request.method == "OPTIONS":
return JsonResponse({'status': 'ok'})
# else, an actual login request:
else:
data = JSONParser().parse(request)
user = authenticate(request, username=data['user'] , password=data['pass'])
if user is not None:
login(request, user)
return JsonResponse({'login_succ': 'ok'});
else:
return JsonResponse({'login_succ': 'fail'});
最后,在Vue中:
api: function(endpoint, method, data) {
var headers = new Headers();
headers.append('content-type', 'application/json');
if (... this is not the first request ever ...)
{
csrftoken = document.cookie.replace(/(?:(?:^|.*;\s*)csrftoken\s*\=\s*([^;]*).*$)|^.*$/, "$1");
headers.append('X-CSRFToken', csrftoken);
}
method = method || 'GET';
var config = {
method: method,
body: data !== undefined ? JSON.stringify(data) : null,
headers: headers,
};
config['credentials'] = 'include';
return fetch(endpoint, config)
.then(response => response.json())
.catch((error) => { console.log(...); });
},
trylogin: function() {
// initial request: just to get the CSRF token
this.api(".../login/", "GET").then(
response => {
this.api(".../login/", "POST", {'username': ..., 'password': ...} ).then(
response => {
if ("login_succ" in response && res["login_succ"] == "ok")
{} // user is logged in
}
);
}
);
}
现在发生了什么,afaiu,是我的初始API请求(不必必须指向等于后续POST请求的端点,对吗?)将CSRF令牌作为cookie获取。每个后续请求都会读取此Cookie,并设置 X-CSRFToken 标头。 Cookie本身也将在后续请求中发送。我不明白为什么两个地方都需要令牌。
这种方法正确吗?我所做的一切都必要吗? (有多余的部分吗?)我对首先应该获取令牌的方式特别感兴趣,并且通常与令牌的生命周期有关。
谢谢。