2016-12-22 55 views
2

我使用Angular 2作爲前端,django rest框架作爲後端。如何同步django rest api中的用戶與Auth0

在前端,我使用Auth0驗證用戶身份(https://auth0.com/docs/quickstart/spa/angular2)。之後我的idtoken發送到我的後臺創建新聞用戶(https://auth0.com/docs/quickstart/backend/python連接auth0 在角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 
    ); 
    } 
}; 

,在這裏我的後端在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) 

也許我我錯了,請幫忙

回答

1

作爲軟件開發通常有接近一個給定的問題的方法不止一種,最合適的解決方案通常需要深入研究了很多小細節。

但是,根據您分享的信息,可以安全地說幾件事情。如果您利用Auth0進行身份驗證,則不應使用密碼在後端創建用戶。密碼用於身份驗證,並且您委派了該部分,這是一件好事,因爲它對您來說工作較少。

儘管如此,仍然存在某種與應用程序相關的每用戶存儲是完全正常的,例如存儲用戶特定的應用程序設置或其他用戶擁有的數據。

爲此,您必須將該數據與可以安全用於在多個驗證會話中識別同一用戶的用戶標識符相關聯地存儲。該標識符應該是ID標記中包含的sub聲明值,因爲每個規範的值都是穩定的,並且允許您在通過Auth0完成身份驗證時識別重複使用的用戶。

結論,您的後端不應該創建新的用戶身份,因爲它位於由Auth0處理的身份驗證範圍內;相反,您應該將數據與用戶標識符關聯起來存儲,以便您持續識別重複使用的用戶。

+0

我完全同意你,但我如何檢索此Id用戶?當我從angular2發送post文件時,我的Python服務器響應正常,但在前面,我收到了一個錯誤消息,這是[object progress event]。服務器不會向我發送任何我在代碼中定義的錯誤。也許我的角度帖子方法是錯誤的。請如果有人可以做一個angularfire2和Django的樣本從auth0檢索用戶ID,這將是偉大的。謝謝 – saius