I've gone through the docs of Provider and Resource of Django OAuth Toolkit, but all I'm able to find is how to 'authenticate' a user
, not how to register
a user.
I'm able to set up everything on my machine, but not sure how to register a user using username & password. I know I'm missing something very subtle. How do I exactly register a user and get an access token in return to talk to my resource servers.
OR
Is it like that I've to first register the user using normal Django mechanism and then get the token of the same?
You can do what you are asking, and its your lucky day. I faced that problem when I first started working with django
and oauth-toolkit
.
The following is my implementation using django-rest-framework
. It will register the user, authenticate and return an oauth response.
The thought is this: Using django models we save the new user using the proper serializers and models. In the same response, we create a new oauth token and return it to the user.
from rest_framework import serializers
import models
from django.utils.translation import gettext_lazy as _
class RegisterSerializer(serializers.ModelSerializer):
confirm_password = serializers.CharField()
def validate(self, data):
try:
user = models.User.objects.filter(username=data.get('username'))
if len(user) > 0:
raise serializers.ValidationError(_("Username already exists"))
except models.User.DoesNotExist:
pass
if not data.get('password') or not data.get('confirm_password'):
raise serializers.ValidationError(_("Empty Password"))
if data.get('password') != data.get('confirm_password'):
raise serializers.ValidationError(_("Mismatch"))
return data
class Meta:
model = models.User
fields = ('username', 'first_name', 'last_name', 'password', 'confirm_password', 'is_active')
extra_kwargs = {'confirm_password': {'read_only': True}}
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status, permissions
from oauth2_provider.settings import oauth2_settings
from braces.views import CsrfExemptMixin
from oauth2_provider.views.mixins import OAuthLibMixin
import json
import models
import serializers
from django.utils.decorators import method_decorator
from django.http import HttpResponse
from django.views.generic import View
from django.views.decorators.debug import sensitive_post_parameters
from django.utils.translation import gettext_lazy as _
from django.db import transaction
class UserRegister(CsrfExemptMixin, OAuthLibMixin, APIView):
permission_classes = (permissions.AllowAny,)
server_class = oauth2_settings.OAUTH2_SERVER_CLASS
validator_class = oauth2_settings.OAUTH2_VALIDATOR_CLASS
oauthlib_backend_class = oauth2_settings.OAUTH2_BACKEND_CLASS
def post(self, request):
if request.auth is None:
data = request.data
data = data.dict()
serializer = serializers.RegisterSerializer(data=data)
if serializer.is_valid():
try:
with transaction.atomic():
user = serializer.save()
url, headers, body, token_status = self.create_token_response(request)
if token_status != 200:
raise Exception(json.loads(body).get("error_description", ""))
return Response(json.loads(body), status=token_status)
except Exception as e:
return Response(data={"error": e.message}, status=status.HTTP_400_BAD_REQUEST)
return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)
return Response(status=status.HTTP_403_FORBIDDEN)
rom django.conf.urls import url
from oauth2_provider import views as oauth2_views
import views
urlpatterns = [
url(r'^user/register/$', views.UserRegister.as_view()),
]
I'm registering user with regular django mechanism combined with django-oauth-toolkit's application client details (client id and client secret key).
I have separate UserRegisterApiView
which is not restricted with token authentication but it checks for client id and client secret key while making post request to register a new user. In this way we are restricting register url access to only registered OAuth clients.
Here is the registration workflow:
client_id
and client_secret
.You have to create the user using normal Django mechanism (For example, you can add new users from admin or from django shell). However, to get access token, OAuth consumer should send a request to OAuth server where user will authorize it, once the server validates the authorization, it will return the access token.
You must register users separately.
django-oauth-toolkit is necessary if you're going to, e.g., support an Alexa Skill that requires "linking" accounts. Amazon needs a token representing an existing user on your system.
django-allauth makes it easy to provide signup via third parties, e.g. Amazon, Google or Slack. You might consider using it to streamline user registration, e.g. during Alexa account "linking".
For a toy Slack command integration I wrote, I added custom code to create new django users based on their unique Slack user id, skipping the OAuth "sign in with Slack" workflow entirely. Only once those django users exist can django-oauth-toolkit issue tokens for them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With