我正在尝试构建客户端/服务器系统,如下所示:服务器是带有一些数据库的django REST,客户端是作为单独的django项目构建的静态HTML / CSS / JS。
我遇到了在客户端通过简单登录表单处理的基本用户身份验证方案。我的想法是进行令牌身份验证,将令牌存储在客户端的localStorage中 - 这就是为什么我采用方法来处理JS的表单提交和令牌服务器的POST。
问题是由于服务器端出现Forbidden (CSRF cookie not set.): /getToken/
错误,我无法从服务器到客户端获取令牌。花了很多时间在它上面,我找不到回答为什么没有设置CSRF cookie,因为我强制执行至少4种强制cookie设置的机制:1){% csrf_token %}
,2)cookie头的手动设置,3){{1 4)在服务器settings.py中删除@ensure_csrf_cookie
中的'django.middleware.csrf.CsrfViewMiddleware',
以下是详细信息:
客户端部分如下所示:
login.html 表单:
MIDDLEWARE_CLASSES
其中<form name="login" method="POST">
{% csrf_token %}
Username<input type="text" name="uname"/>
Password<input type="password" name="psswd"/>
<input type="button" onclick="do_login(this.form)" value="Login"/>
<input type="reset" value="Reset"/>
</form>
位于以下脚本中。请注意do_login()
包括在内......
login_script.js :
{% csrf_token %}
其中function do_login(form) {
var csrftoken = getCookie('csrftoken');
uname = form.uname.value;
psswd = form.psswd.value;
var req = new XMLHttpRequest();
var url = "http://localhost:8000/getToken/";
var params = JSON.stringify({ username: uname, password: psswd });
req.open("POST", url, true);
req.setRequestHeader("X-CSRFToken", csrftoken);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.onreadystatechange = function() {
if(req.readyState == XMLHttpRequest.DONE && req.status == 200) {
alert(http.responseText);
}
}
req.send(params);}
是来自django教程的复制和粘贴功能(它似乎返回一些cookie,所以我认为它是正确的)
views.py :
getCookie
我把@ensure_csrf_cookie
def user_login(request):
return render(request, 'login.html', {})enter code here
强制输入cookie但没有成功......
在服务器端我有一个视图
@ensure_csrf_cookie
这基本上是稍微重新定义的django的内置@require_POST
def getToken(request):
serializer = AuthTokenSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user)
response = HttpResponse({'token': token.key}, content_type="application/json")
response["Access-Control-Allow-Origin"] = "*"
return response
(因为我无法以任何其他方式克服CORS问题)