简体   繁体   English

最简单的AngularJS应用程序,具有对DRF的会话身份验证

[英]Simplest AngularJS App to with Session Authentication to DRF

I have been banging my head against the wall for far too long trying to get session authentication to work in AngularJS with the basic Django REST Framework setup. 试图获取会话身份验证以在基本Django REST Framework安装程序中在AngularJS中工作时,我已经摸不着头脑了太久了。 I've read through blogs dozens of stack overflow questions and answers, and I'm just not getting it. 我已经通读了博客的数十个堆栈溢出问题和答案,但我只是不明白。 I have a large application that I'm working on, but in order to facilitate an answer to this issue, I've produced a minimalist AngularJS App on top of a fork of the bare-bones Django REST Framework Tutorial code here . 我有一个正在处理的大型应用程序,但是为了方便对此问题的解答,我在这里的准系统Django REST Framework Tutorial代码的分支之上制作了一个简约的AngularJS App。 (All the front-end dependencies are included in the fork.) Just do pip install -r requires.txt , python manage.py makemigrations snippets , python manage.py migrate , and then python manage.py runserver . (所有的前端依赖项都包含在fork中。)只需执行pip install -r requires.txt python manage.py makemigrations snippetspython manage.py makemigrations snippetspython manage.py migrate python manage.py makemigrations snippetspython manage.py runserver

The main code of interest is here: 感兴趣的主要代码在这里:

 "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> 

My nested GETs and POSTs are ugly and obviously not how I would really do this in an application. 我嵌套的GET和POST很丑陋,显然不是我在应用程序中真正做到的方式。 But I think it should work , and it doesn't. 但是我认为它应该起作用 ,但事实并非如此。 I've been using postman and chrome to figure out the problem. 我一直在用邮递员和Chrome来解决问题。 The root of the problem seems to be that when I use AngularJS, the POST does not come back with a Set-Cookie that includes sessionid. 问题的根源似乎是当我使用AngularJS时,POST并没有返回包含sessionid的Set-Cookie。 (When I use the browser it does.) Thus, when it tries to get the user information it doesn't have the cookie set, and it comes into Django as an AnonymousUser. (当我使用浏览器时,它会这样做。)因此,当它尝试获取用户信息时,它没有设置cookie,而是作为AnonymousUser进入Django。 Any help that anyone can offer is greatly appreciated! 任何人都可以提供的任何帮助,我们将不胜感激!

So the question is Why doesn't this work in AngularJS, but it does with the browser? 所以问题是为什么这在AngularJS中不起作用,但在浏览器中起作用? I would also appreciate input on best practices, or better ways to solve this problem. 我也很感谢您提供有关最佳做法或解决此问题的更好方法的意见。 (New DRF endpoint, use $resource, etc)? (新的DRF端点,使用$ resource等)?

Alright, after fiddling around with this problem more this morning I got the answer. 好吧,今天早上更多地摆弄这个问题后,我得到了答案。 For the DRF default api login view, the data must be submitted as a form. 对于DRF默认api登录视图,数据必须以表单的形式提交。 Therefore, this ended up being the solution: 因此,这最终成为解决方案:

.run(function($rootScope, $location, $http) {
$http.get('api/auth/login/').then(function successCallback(response){
console.log(response);
$http({
    "method": "POST",
    "url": 'api/auth/login/',
    "data": $.param({username:'username', password:'password', next:'/api/currentuser'}),
    "headers": {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(
  function successCallback(response){
    console.log(response);
  })})

}); });

I would still be very interested to learn the "right" way to do this. 我仍然会对学习“正确”的方法很感兴趣。 Should I build a separate DRF login view? 我应该建立一个单独的DRF登录视图吗? Should I use Angular $resource instead of $http calls? 我应该使用Angular $ resource而不是$ http调用吗? I would appreciate any and all inputs. 我将不胜感激。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM