-
Notifications
You must be signed in to change notification settings - Fork 442
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide django-rest-framework-simplejwt integration #407
Provide django-rest-framework-simplejwt integration #407
Comments
Here is the class TokenObtainSerializer(serializers.Serializer):
username_field = User.USERNAME_FIELD
default_error_messages = {
'no_active_account': _('No active account found with the given credentials')
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields[self.username_field] = serializers.CharField()
self.fields['password'] = PasswordField()
def validate(self, attrs):
authenticate_kwargs = {
self.username_field: attrs[self.username_field],
'password': attrs['password'],
}
try:
authenticate_kwargs['request'] = self.context['request']
except KeyError:
pass
self.user = authenticate(**authenticate_kwargs)
# Prior to Django 1.10, inactive users could be authenticated with the
# default `ModelBackend`. As of Django 1.10, the `ModelBackend`
# prevents inactive users from authenticating. App designers can still
# allow inactive users to authenticate by opting for the new
# `AllowAllUsersModelBackend`. However, we explicitly prevent inactive
# users from authenticating to enforce a reasonable policy and provide
# sensible backwards compatibility with older Django versions.
if self.user is None or not self.user.is_active:
raise exceptions.AuthenticationFailed(
self.error_messages['no_active_account'],
'no_active_account',
)
return {}
@classmethod
def get_token(cls, user):
raise NotImplementedError('Must implement `get_token` method for `TokenObtainSerializer` subclasses')
class TokenObtainPairSerializer(TokenObtainSerializer):
@classmethod
def get_token(cls, user):
return RefreshToken.for_user(user)
def validate(self, attrs):
data = super().validate(attrs)
refresh = self.get_token(self.user)
data['refresh'] = str(refresh)
data['access'] = str(refresh.access_token)
return data |
I tried playing around with decorated_token_obtain_pair_view = (
swagger_auto_schema(
method='post',
responses={status.HTTP_200_OK: TokenObtainPairResponseSerializer}
)(TokenObtainPairView.as_view())
)
decorated_token_refresh_view = (
swagger_auto_schema(
method='post',
responses={status.HTTP_200_OK: TokenRefreshResponseSerializer}
)(TokenRefreshView.as_view())
) Where I created my own
All of the Token views share a common base |
So the best solution I could come up with is: from drf_yasg.utils import swagger_auto_schema
from rest_framework import serializers, status
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView, TokenVerifyView
class TokenObtainPairResponseSerializer(serializers.Serializer):
access = serializers.CharField()
refresh = serializers.CharField()
def create(self, validated_data):
raise NotImplementedError()
def update(self, instance, validated_data):
raise NotImplementedError()
class DecoratedTokenObtainPairView(TokenObtainPairView):
@swagger_auto_schema(responses={status.HTTP_200_OK: TokenObtainPairResponseSerializer})
def post(self, request, *args, **kwargs):
return super().post(request, *args, **kwargs)
class TokenRefreshResponseSerializer(serializers.Serializer):
access = serializers.CharField()
def create(self, validated_data):
raise NotImplementedError()
def update(self, instance, validated_data):
raise NotImplementedError()
class DecoratedTokenRefreshView(TokenRefreshView):
@swagger_auto_schema(responses={status.HTTP_200_OK: TokenRefreshResponseSerializer})
def post(self, request, *args, **kwargs):
return super().post(request, *args, **kwargs)
class TokenVerifyResponseSerializer(serializers.Serializer):
def create(self, validated_data):
raise NotImplementedError()
def update(self, instance, validated_data):
raise NotImplementedError()
class DecoratedTokenVerifyView(TokenVerifyView):
@swagger_auto_schema(responses={status.HTTP_200_OK: TokenVerifyResponseSerializer})
def post(self, request, *args, **kwargs):
return super().post(request, *args, **kwargs) I had to subclass the Is this the correct way to do this? Is there a more succinct solution? |
Yeah, this seems right. You could also probably wrap the |
@axnsan12 Thanks for the comment. When I tried that, it seemed like the different |
Also, if I'm not actually using the Serializers I've defined (they are soley for |
Hello, Try also to use DecoratedTokenRefreshView, I'm getting the access token but ones that I get I don't understand how to give to the schema view... I added the serializers, in the urls.py I added:
Did I'm missing something? Thank you :) |
@estyxx Please try: jazzband/djangorestframework-simplejwt#145 |
@johnthagen yes, I included those serializers in my code, but I'm confusing about how to use them in urls... 🤔 Because as I did, I can not access to the swagger page...
|
Documentation for this is now included upstream: https://django-rest-framework-simplejwt.readthedocs.io/en/latest/drf_yasg_integration.html |
We are using
django-rest-framework-simplejwt
to support JWT tokens.By default,
drf-yasg
seems to create correctPOST
parameters, but JWT endpoints return different values than they consume.For example:
http://localhost:8000/api/token/
The default generated schema from
drf-yasg
:Could
drf-yasg
support this out of the box? If not, I would be happy to try to contribute some docs about how to work around this so that others could discover how to support this in the future. I'm just not sure what the best way forward is.The text was updated successfully, but these errors were encountered: