Angular authentication (and authorization) based on Django REST Framework tokens, written in Coffee Script
Authenticate AngularJS app with Django (REST framework) backend using Token Based Authentication.
- About this module
- [How it works] (#how-it-works)
- Installation
- [Basic Usage] (#basic-usage)
At the time there was no module like this available - so we've created one. We love simplicity! We've put much effort in making this module as slim and easy to use as possible. Angular-DRF-Auth is based on Token Authentication in Django REST Framework with the following features:
- simple front-end template with a log-in form
- redirection to the log-in form if unlogged user tries to enter an application
- authorisation rights based on assigned roles
- defining if particular webpage should require authentication (or authorization)
- Angular UI-Router support
- hide/display selected elements using
hasPermission
andhasPermissionToObject
directives depending on granted permissions
-
A user wants to enter restricted page.
-
Angular-DRF-Auth checks if there is cookie 'token' for that site, if not it redirects to
/#/login
at this site./#/login
url is configured to be managed byLoginCtrl
which is a part of AngularAuth library. -
LoginCtrl
posts user and password to backend's url -/api-token-auth
that is managed by Django REST Framework. If username and password are correct, api-token-auth returns the token in the response. -
Token is stored as a cookie and common authentication http header is set to Token and the token value.
-
Next there is another backend call to
/check-auth
which is any url managed by Django REST Framework which returns user in the response. -
The user is set to angular
$rootScope
to session object. If the token cookie exists, angular auth calls/check-auth
to get the user and set it to the scope, it happens always when the page is refreshed. -
Angular auth provides the directive has-permission-to-object which can be used to show/hide page elements based on permissions of the user groups.
- Download this module and its dependencies:
# from the terminal at the root of your project
bower install angular-drf-auth --save
<div has-permission-to-object="write_project" user="user" object="project"/>
User is an object which is returned by /check-auth
url, project is an example name which can be anything you want to check user access on it - It has to have 'visibility' property which is the table of the object with permission property:
project.visibility = [{permission: 1}, {permission: 2}]
That means that user has to have at least one of the group permission with id=1
or id=2
to have an access to the project object.
Has-permission-to-object
directive deals also well with the angular-chosen select components and is able to enable/disable them. The directive can also 'negate' the permission check, it can be done with '!' sign, f.e.
<div has-permission-to-object="!write_project" user="user" object="project"/>
That means that this div will be displayed only for users that don't have write_project group permission.
.config(function ($stateProvider, $urlRouterProvider) {
// redirect to project list on /
$urlRouterProvider.when('', '/check');
// define states
$stateProvider
.state('check', {
url: '/check',
})
.state('login', {
url: '/login',
templateUrl: 'common/templates/login.html',
controller: 'LoginCtrl',
resolve: {
}
})
}
also in your application you have to add service with url to your api:
.factory(
'Config', function() {
return {
apiUrl: 'http://localhost:8080/api'
};
});
url(r'^api-token-auth/', 'rest_framework.authtoken.views.obtain_auth_token'),
url(r'^check-auth/', CheckAuthView.as_view()),
class CheckAuthView(generics.views.APIView):
def get(self, request, *args, **kwargs):
return Response(UserWithFullGroupsSerializer(request.user).data)
class UserWithFullGroupsSerializer(serializers.ModelSerializer):
groups = UserGroupSerializer(many=True)
class Meta:
model = User
depth = 2
fields = ('id', 'first_name', 'last_name', 'username', 'groups', 'password', 'user_permissions', 'is_superuser', 'is_staff', 'is_active')
class UserGroupSerializer(serializers.ModelSerializer):
class Meta:
model = Group
depth = 1
Response:
{
"id": 1,
"first_name": "",
"last_name": "",
"username": "admin",
"groups": [
{
"id": 6,
"name": "GR",
"permissions": [
{
"id": 261,
"name": "Save project",
"content_type": 87,
"codename": "save_project"
}
]
},
{
"id": 5,
"name": "Admin",
"permissions": [
{
"id": 262,
"name": "Approve project",
"content_type": 87,
"codename": "approve_project"
}
]
}
],
"password": "pbkdf2_sha256",
"user_permissions": [],
"is_superuser": true,
"is_staff": true,
"is_active": true
}