wagnerdelima / drf-social-oauth2

drf-social-oauth2 makes it easy to integrate Django social authentication with major OAuth2 providers, i.e., Facebook, Twitter, Google, etc.
https://drf-social-oauth2.readthedocs.io/en/latest/
MIT License
270 stars 34 forks source link

Creating Tokens Manually #118

Closed futurbotconsolidated closed 2 years ago

futurbotconsolidated commented 2 years ago

I am actually trying to include phone number authentication and tried to implement it with djangorestframework-simplejwt . Since my app also uses drf-social-oauth2, I can't use djangorestframework-simplejwt because

According the to [django-rest-framework-jwt] it will not let you try another authentication if:

your token is invalid your Authorization header does not match the syntax Authorization: with being an actual string without whitespaces.

If your credentials do not meet that format, django-rest-framework-jwt will directly reject any authentication attempt.

If we can get an extension in drf-social-oauth2 by which we can create tokens manually bypassing grant type so we don't have to use multiple authentication classes and manage 2 token tables separatly.

Referece: https://github.com/jazzband/djangorestframework-simplejwt/blob/master/docs/creating_tokens_manually.rst

futurbotconsolidated commented 2 years ago

application = Application.objects.last() expires = timezone.now() + timezone.timedelta(seconds=oauth2_settings.ACCESS_TOKEN_EXPIRE_SECONDS) access_token = AccessToken( user=user, scope='read write groups', expires=expires, token=common.generate_token(), application=application ) access_token.save() refresh_token = RefreshToken( user=user, token=common.generate_token(), application=application, access_token=access_token ) refresh_token.save()

Chappie74 commented 1 year ago

For anyone in the future looking to this, to create a custom view for providing the access token here is my approach.

A cleaner approach I found is to send the http request internally in your view (rather than messing with the models) as you would when using the /token endpoint.

Here is a quick snippet on how to do this:

from django.http import HttpRequest, QueryDict
from oauth2_provider.views import TokenView
from rest_framework.response import Response

...
...

# create an instance of the token view
token_view = TokenView.as_view()

# construct your data for the request
data = {
    'grant_type': 'password',
    'username': user.email,
    'password': password,
    'client_id': client_id,
}
# construct a request to send to token view
token_request = HttpRequest()
token_request.method = 'POST'
token_request.POST = QueryDict('', mutable=True)
token_request.POST.update(data)

# send the request and capture response
response = token_view(token_request)
return response

Sample response

{
    "access_token": "dKFK4Y1XSh7dkAiIg53lhjD7KCa6AO",
    "expires_in": 3600,
    "token_type": "Bearer",
    "scope": "read write",
    "refresh_token": "OZ7185rJgWCNZcG4oQkKBzdNLh879V"
}

ps. this was generated by chatGPT with some modifications from me.