0% found this document useful (0 votes)
12 views13 pages

Authenticate Using Django Rest Framework and Angular: Richard Tier

Uploaded by

odeinanyanwu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views13 pages

Authenticate Using Django Rest Framework and Angular: Richard Tier

Uploaded by

odeinanyanwu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

Richard Tier

Authenticate using Django


Rest Framework and Angular
In a previous post we went through how to authenticated using a DRF endpoint.

This post will expand on how to achieve persistent login with a one page app
using Angular. Note as there are 2 frameworks in play there will be some need to
workaround integrations problems. It doesn’t get messy, which is a testiment to
the quality of the respective frameworks!

Demo – its a silly microblog tool in which you can create an account and log into
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
it. github here

Note my folder strucure is like so:

project/
urls.py
settings.py
static/
js/
app.js
...[all third party js files]...
apps/
core/
views.py
urls.py
accounts/
urls.py
api/
views.py
serializers.py
authentication.py

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Create the Angular module
In app.js we create a module that will call the DRF endpoints in order to
authenticate:

1 angular.module('authApp', ['ngResource']).
2 config(['$httpProvider', function($httpProvider){
3 // django and angular both support csrf tokens. This tells
4 // angular which cookie to add to what header.
5 $httpProvider.defaults.xsrfCookieName = 'csrftoken';
6 $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
7 }]).
8 factory('api', function($resource){
9 function add_auth_header(data, headersGetter){
10 // as per HTTP authentication spec [1], credentials must be
11 // encoded in base64. Lets use window.btoa [2]
12 var headers = headersGetter();
13 headers['Authorization'] = ('Basic ' + btoa(data.username +
14 ':' + data.password));
15 }
16 // defining the endpoints. Note we escape url trailing dashes: Angular
17 // strips unescaped trailing slashes. Problem as Django redirects urls
18 // not ending in slashes to url that ends in slash for SEO reasons, unless
19 // we tell Django not to [3]. This is a problem as the POST data cannot
20 // be sent with the redirect. So we want Angular to not strip the slashes!
21 return {
22 auth: $resource('/api/auth\\/', {}, {
23 login: {method: 'POST', transformRequest: add_auth_header},
24 logout: {method: 'DELETE'}
25 }),
26 users: $resource('/api/users\\/', {}, {
27 create: {method: 'POST'}
28 })
29 };
30 }).
31 controller('authController', function($scope, api) {
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
31 controller('authController', function($scope, api) {
32 // Angular does not detect auto-fill or auto-complete. If the browser
33 // autofills "username", Angular will be unaware of this and think
34 // the $scope.username is blank. To workaround this we use the
35 // autofill-event polyfill [4][5]
36 $('#id_auth_form input').checkAndTriggerAutoFillEvent();
37
38 $scope.getCredentials = function(){
39 return {username: $scope.username, password: $scope.password};
40 };
41
42 $scope.login = function(){
43 api.auth.login($scope.getCredentials()).
44 $promise.
45 then(function(data){
46 // on good username and password
47 $scope.user = data.username;
48 }).
49 catch(function(data){
50 // on incorrect username and password
51 alert(data.data.detail);
52 });
53 };
54
55 $scope.logout = function(){
56 api.auth.logout(function(){
57 $scope.user = undefined;
58 });
59 };
60 $scope.register = function($event){
61 // prevent login form from firing
62 $event.preventDefault();
63 // create user and immediatly login on success
64 api.users.create($scope.getCredentials()).
65 $promise.
66 then($scope.login).
67 catch(function(data){
68 alert(data.data.username);
69 });
70 };
71 });
72
73 // [1] https://tools.ietf.org/html/rfc2617
74 // [2] https://developer.mozilla.org/en-US/docs/Web/API/Window.btoa
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
74 // [2] https://developer.mozilla.org/en-US/docs/Web/API/Window.btoa
75 // [3] https://docs.djangoproject.com/en/dev/ref/settings/#append-slash
76 // [4] https://github.com/tbosch/autofill-event
77 // [5] http://remysharp.com/2010/10/08/what-is-a-polyfill/

Create the Angular view


Django and Angular both use curly braces to denote variables. Below we want
Django to take care of defining the user (‘{{user.username}}’) based on the value
passed in the Context to the template, while Angular should take care of
everything else. We use verbatim template tag to prevent Django from stealing
Angular’s thunder. In one_page_app.html we do:

1 <html ng-cloak ng-app>


2 <head>
3 <link rel="stylesheet" href="/static/js/angular/angular-csp.css"/>
4 <link rel="stylesheet" href="/static/js/bootstrap/dist/css/bootstrap.min.css"/>
5 </head>
6 <body>
7 <div class="navbar navbar-fixed-bottom" ng-controller="authController"
8 ng-init="user='{{user.username}}'">
9 {% verbatim %}
10 <div ng-show="user" class="navbar-form navbar-right">
11 <input type="submit" class="btn btn-default" ng-click="logout()"
12 value="logout {{user}}"/>
13 </div>
14 <div ng-hide="user">
15 <form id="id_auth_form" class="navbar-form navbar-right"
16 ng-submit="login()">
17 <div class="form-group">
18 <input ng-model="username" required name="username"
19 type="text" placeholder="username" class="form-control">
20 </div>
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
20 </div>
21 <div class="form-group">
22 <input ng-model="password" required name="password" type="password"
23 placeholder="password" class="form-control">
24 </div>
25 <div class="btn-group">
26 <input type="submit" class="btn btn-default" value="login">
27 <input type="submit" class="btn btn-default" value="register"
28 ng-click="register($event)">
29 </div>
30 </form>
31 </div>
32 </div>
33 </body>
34 <script src="/static/js/jquery/jquery.js"></script>
35 <script src="/static/js/bootstrap/dist/js/bootstrap.min.js"></script>
36 <script src="/static/js/angular/angular.min.js"></script>
37 <script src="/static/js/angular-resource/angular-resource.min.js"></script>
38 <script src="/static/js/autofill-event/src/autofill-event.js"></script>
39 <script src="/static/js/app.js"></script>
40 </html>
41 {% endverbatim %}

Requirements
Bower is fantastic tool to manage front-end requirements. Lets define
bower.json like so:

1 {
2 "dependencies": {
3 "angular": "1.3.0-build.2419+sha.fe0e434",
4 "angular-resource": "1.3.0-build.2419+sha.fe0e434",
5 "autofill-event": "1.0.0",
6 "jquery": "1.8.2",
7 "bootstrap": "3.0.0",
8 }
9 }
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
DRF Endpoint
We also need to update the apps.accounts.api.AuthView created in previous post:
we need to call django.contrib.auth.login in order to attach the session id the
request object, and cause the creation a Set-Cookie header on the respons,
which causes the browser to create the defined cookie and so we will achieve
persistent login upon reloading the page:

1 from django.contrib.auth import login, logout


2
3
4 class AuthView(APIView):
5 authentication_classes = (QuietBasicAuthentication,)
6
7 def post(self, request, *args, **kwargs):
8 login(request, request.user)
9 return Response(UserSerializer(request.user).data)
10
11 def delete(self, request, *args, **kwargs):
12 logout(request)
13 return Response({})

django.contrib.auth.logout stops the session, and sends instructions to browser


to make the cookie expire.

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Serving the view
We also of course need to serve the one_page_app.html, so in core.views.py we
do

1 from django.views.generic.base import TemplateView


2
3
4 class OnePageAppView(TemplateView):
5 template_name = 'one_page_app.html'

And in core.urls we route a url to the Django view:

1 from django.conf.urls import patterns, include, url


2
3 from . import views
4
5
6 urlpatterns = patterns('',
7 url(r'^$', views.OnePageAppView.as_view(), name='home'),
8 )

With this all plugged in we have a one page app that:

– Shows login form if user isn’t authenticated with their Django session cookie.
– Shows logout if user is authenticated by either session cookie or username and
password.
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
– Allows logging in in a RESTful way.
– Allows creating new user and automatically logs after creation.
– Alerts login and registration errors.
– Took only about 150 lines of code to achieve.

Share this:

Twitter 7 Facebook 4 Google

Loading...

March 15, 2014 rikatee

← Check credentials using Django JSON schema validation with Django

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Rest Framework Rest Framework →

4 thoughts on “Authenticate using Django Rest


Framework and Angular”

Pingback: Check credentials using Django Rest Framework | Richard Tier ~

michael snook says:


March 15, 2014 at 5:41 am

Obviously you must call this Djangular.

Reply

rikatee says:
March 15, 2014 at 5:19 pm

Someone beat us to it

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
https://github.com/appliedsec/djangular

Reply

realpython.com says:
March 17, 2014 at 3:16 am

ok how about djugular. Authentication — straight at the neck

Leave a Reply

Enter your comment here...

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Search … Search …

Archives Archives

March 2014 March 2014

February 2014 February 2014

Categories Categories

django django

django-rest-framework django-rest-framework

JSON JSON

REST REST

testing testing

Uncategorized Uncategorized

Meta Meta
open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com
Register Register

Log in Log in

Entries RSS Entries RSS

Comments RSS Comments RSS

WordPress.com WordPress.com

Blog at WordPress.com. ~ The Syntax Theme.

Follow

Follow “Richard
Tier”
Get every new post
delivered to your Inbox.

Enter your email address

Sign me up

open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com

You might also like