【发布时间】:2017-08-13 23:07:50
【问题描述】:
长期以来,我一直在努力让会话身份验证在 AngularJS 中与基本的 Django REST 框架设置一起工作。我已经通过博客阅读了数十个堆栈溢出问题和答案,但我就是不明白。我有一个正在开发的大型应用程序,但为了帮助解决这个问题,我在基本的 Django REST 框架教程代码 here 的一个分支之上制作了一个极简主义的 AngularJS 应用程序。 (所有前端依赖都包含在 fork 中。)只需执行pip install -r requires.txt、python manage.py makemigrations snippets、python manage.py migrate,然后是python manage.py runserver。
感兴趣的主要代码在这里:
"use strict";
var geoint = angular.module('snippets', [
'ngRoute',
'ngCookies',
'ngAnimate',
'ngResource',
'snippets.controllers',
])
.config(function ($routeProvider, $httpProvider) {
$httpProvider.defaults.withCredentials = true;
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
$routeProvider
.when('/', {
title:'Snippets - Home',
templateUrl: STATIC_URL + 'snippets/partials/snippets.html',
controller: 'SnippetsCtrl'
})
.otherwise({
redirectTo: '/'
});
})
.run(function($rootScope, $location, $http) {
// Get a CSRF Token
$http.get('api/auth/login/?next=/api/').then(
function successCallback(response){
console.log(response);
// Post should come back with Set-Cookie sessionid, but it doesn't!
$http.post('api/auth/login/', {username:'username', password:'password'}).then(
function successCallback(response){
console.log(response);
// Get this user's information
$http.get('api/currentuser/').then(
function successCallback(response){
console.log(response);
})
})
},
function errorCallback(response){
alert(response);
}
);
});
<!DOCTYPE html>
<html lang="en" ng-app="pc2">
{% load static from staticfiles %}
<head>
<meta charset="UTF-8">
<title ng-bind="title">PC2</title>
<script>var STATIC_URL = "{% static "" %}";</script>
<link rel="stylesheet" type="text/css" href="{% static "resources/css/complete.min.css" %}">
{% if debug %}
<script src="{% static "resources/js/_bower.js" %}"></script>
<script src="{% static "resources/js/app.js" %}"></script>
<script src="{% static "resources/js/controllers.js" %}"></script>
<script src="{% static "resources/js/directives.js" %}"></script>
<script src="{% static "resources/js/filters.js" %}"></script>
<script src="{% static "resources/js/services.js" %}"></script>
{% else %}
<script src="{% static "resources/js/complete.min.js" %}"></script>
{% endif %}
</head>
<body>
{% load static from staticfiles %}
<div ng-include="'{% static "resources/partials/navbar.html" %}'"></div>
<div ng-view class="container-fluid main-view"></div>
</body>
</html>
我的嵌套 GET 和 POST 很丑陋,显然我不会在应用程序中真正做到这一点。但我认为它应该工作,但它没有。我一直在使用邮递员和 chrome 来解决问题。问题的根源似乎是当我使用 AngularJS 时,POST 没有返回包含 sessionid 的 Set-Cookie。 (当我使用浏览器时,它会这样做。)因此,当它尝试获取用户信息时,它没有设置 cookie,并且它作为 AnonymousUser 进入 Django。非常感谢任何人提供的任何帮助!
所以问题是 为什么这在 AngularJS 中不起作用,但在浏览器中却起作用?我也希望能提供有关最佳实践或解决此问题的更好方法的意见。 (新的 DRF 端点,使用 $resource 等)?
【问题讨论】:
-
您是否尝试过设置
withCredentials标志?参见例如developer.mozilla.org/en-US/docs/Web/HTTP/… -
我不完全确定这是否是您的问题,但我会看看您如何在 POST 请求中传递用户名/密码参数。尝试查看此线程以供参考:stackoverflow.com/questions/31572937/…
-
您能否提供一个使用 angularjs 登录的示例?我克隆了存储库,它似乎工作正常。
-
jonrsharpe,应该由
$httpProvider.defaults.withCredentials = true;Linovia 处理。当您转到 localhost:8000 并查看控制台输出时,您应该看到“找不到用户”。问题是 app.js 文件中的最终 GET 请求未通过身份验证。所以我认为它行不通。请注意,如果您使用 admin 或使用浏览器的 api 手动登录,那么您将获得一个 sessionid cookie,然后 Angular 代码将成功。 -
嗯,我只是想出了一些可以将问题推回的东西。问题是 POST 没有做我认为它正在做的事情。无论用户名和密码是什么,它都会得到一个 200 状态码(即使它们是错误的)。
标签: angularjs django authentication django-rest-framework session-cookies