如何将 django rest api 中的用户与 Auth0 同步
Posted
技术标签:
【中文标题】如何将 django rest api 中的用户与 Auth0 同步【英文标题】:How to synchronize users in django rest api with Auth0 【发布时间】:2017-05-07 18:17:51 【问题描述】:我使用 Angular 2 作为前端,django rest 框架作为后端。
在前端,我使用 Auth0 来验证用户(https://auth0.com/docs/quickstart/spa/angular2)。在我将 idtoken 发送到我的后端以创建新闻用户之后(https://auth0.com/docs/quickstart/backend/pythonconnected auth0 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
);
;
这里是我在 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 处理的身份验证范围;相反,您应该将数据与允许您持续识别重复用户的用户标识符相关联。
【讨论】:
我完全同意你的看法,但我如何检索这个 ID 用户?当我从 angular2 发送帖子文件时,我的 Python 服务器响应正常,但在前面我收到一条错误消息,即 [object progress event]。服务器不会向我发送我在代码中定义的任何错误。也许我的角度发布方法是错误的。如果有人可以做一个 angularfire2 和 django 示例来从 auth0 检索用户 ID,那就太好了。谢谢【参考方案2】:请参考,它确实包含带有 JWT、Auth() 的 Rest Api 的完整演示,Api 与 angular(1) js 集成在前端
https://github.com/rmemon/Angular-JS-django-rest-framework-jwt
【讨论】:
请阅读。我的意思是 Angular 2 和 Auth0。你能帮助 Auth0 和 django 后端吗 我只推荐关于 django 用户模型中的 Auth 和 rest API -- 谢谢 Rahil以上是关于如何将 django rest api 中的用户与 Auth0 同步的主要内容,如果未能解决你的问题,请参考以下文章