4
votes

I use Angular 2 as frontend, django rest framework as backend.

At frontend I use Auth0 for authenticating user (https://auth0.com/docs/quickstart/spa/angular2 ). and after I send the idtoken to my backend for creating news users (https://auth0.com/docs/quickstart/backend/python connected auth0 the code in angular 2:

import { Component } from '@angular/core';
import { Auth }      from './auth.service';
import { AuthHttp }  from 'angular2-jwt';
import { Http }      from '@angular/http';
import 'rxjs/add/operator/map';

@Component({
  selector: 'ping',
  templateUrl: 'app/ping.template.html'
})

export class PingComponent {
  API_URL: string = 'http://localhost:8000/callback/';
  message: string;

  constructor(private auth: Auth, private http: Http, private authHttp: AuthHttp) {}

// the code for sending idtoken to my backend
//correct me please if    I am wrong
  public securedPing() {

    this.message = '';
    this.authHttp.post(`${this.API_URL}`,localStorage.getItem('id_token'))
      .map(res => res.json())
      .subscribe(
        data => this.message= data.text,
        error => this.message = error._body || error
      );
  }
};

and here the code of my backend in Django :

 from django.http import Http404

    from rest_framework.views import APIView
    from rest_framework.response import Response
    from rest_framework import status
    from django.http import JsonResponse
    from places_management.serializers import UserSerializer
    from django.contrib.auth.models import User
    import jwt

    class Callbacks(APIView):
        authentication_classes = []
        permission_classes = []

        def authenticate(error):

            return Response(error,401)

        def post(self, request, format=None):
            """
            Callback for after user logs in. It creates a
            django auth user if one does not exist, username is the
            user_id retured frrom auth0
            """
            #token = request.META['HTTP_AUTHORIZATION'].split('JWT ')[1]
            auth = request.META.get('HTTP_AUTHORIZATION', None)

            if not auth:
                return Response({'code': 'authorization_header_missing', 'description': 'Authorization header is expected'},status=status.HTTP_401_UNAUTHORIZED)

            parts = auth.split()

            if parts[0].lower() != 'bearer':
                return authenticate({'code': 'invalid_header', 'description':     'Authorization header must start with Bearer'})
            elif len(parts) == 1:
                return authenticate({'code': 'invalid_header', 'description':     'Token not found'})
            elif len(parts) > 2:
                return authenticate({'code': 'invalid_header', 'description': 'Authorization header must be Bearer + \s + token'})

            token = parts[1]
            try:
                payload = jwt.decode(
                    token,
                    'Z-HWF9cDxGTk7aMZe0A2Ygt81vGBPihz1FCRzJfS87B0mCw1ClQzp1HgA7U3WsSg',
                    audience='GwtnxdwhMWsuGz6JxabDkrNvFhAvn5ZJS'
                    )
            except jwt.ExpiredSignature:
                return authenticate({'code': 'token_expired', 'description': 'token is expired'})
            except jwt.InvalidAudienceError:
                return authenticate({'code': 'invalid_audience', 'description': 'incorrect audience, expected: GwtnxdwhMWsuGz6JxabDkrNvFhvn5ZJS'})
            except jwt.DecodeError:
                return authenticate({'code': 'token_invalid_signature', 'description': 'token signature is invalid'})

            #try:
                #payload = settings.JWT_AUTH['JWT_DECODE_HANDLER'](token)
            #except:
                #return Response('text',status=status.HTTP_401_UNAUTHORIZED)

            user = User.objects.filter(username=payload['sub']).first()
            if(user is None):
                password = User.objects.make_random_password()
                user = User.objects.create_user(
                    username=payload['sub'], password=password)

            serializer = UserSerializer(user, context={'user': user})
            return Response(serializer.data, status=status.HTTP_200_OK)

Maybe I am wrong, please help

2

2 Answers

3
votes

As usual in software development there's more than one way to approach a given problem and the most suitable solution usually requires delving into a lot of small details.

However, there are a few things that are safe to say based on the information you shared. If you're leveraging Auth0 for use authentication you should not then be creating users in your back-end with passwords. Passwords are for authentication and you delegated that part, which is a good thing, as it's less work for you.

Having said that it's completely normal to still have some kind of per-user storage associated with your application, for example, to store user-specific application settings or other user owned data.

For this you'll have to store that data in association with a user identifier that can be safely used to identify the same user across multiple authentication sessions. That identifier should be the sub claim value contained within the ID Token given that per specification that value is stable and will allow you to identify recurring users when they complete the authentication through Auth0.

In conclusion, you back-end should not create new user identities as that is within the scope of authentication which is handled by Auth0; instead you should store data in association with a user identifier that allows you to continuously identify recurring users.

-1
votes

Please Refer , It do contain full demo of Rest Api With JWT, Auth() , Api Integrated in front end with angular(1) js

https://github.com/rmemon/Angular-JS-django-rest-framework-jwt