How to use DRF JWT resfresh - django

I can generate token,However, after the Web accesses me with the first token, I cannot give a new token
I set it in setting
'JWT_ALLOW_REFRESH': True,
But I don't know how to get a new one
Please let me know if you need anything else
I thought that after this setting is completed, the token will be changed automatically Medium expiration time,Looks like I'm wrong

based on this post, you have to do the following:
request the token http post http://127.0.0.1:8000/api/token/ username=vitor password=123
this returns a access token and a refresh token
use the access token to access the site
if the access token expires (site returns 403) use the refresh token to get a new valid access token http post http://127.0.0.1:8000/api/token/refresh/ refresh=REFRESHTOKEN
Note that the refresh token can also expire, then you would have to restart the flow.
EDIT: code snippets
install library
pip install djangorestframework_simplejwt
docs of the library
settings.py
REST_FRAMEWORK = {
...
'DEFAULT_AUTHENTICATION_CLASSES': (
...
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
...
}
urls.py
from django.urls import path
from rest_framework_simplejwt import views as jwt_views
urlpatterns = [
# Your URLs...
path('api/token/', jwt_views.TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', jwt_views.TokenRefreshView.as_view(), name='token_refresh'),
]

Related

How to use Postman to authenticate Google Login with dj_rest_auth

So I am following the official documentation for Google sign in with DjangoRestFramework using DJ Rest Auth (this link)
I intend to authenticate with Postman Oauth2 (by following the guide and generating an Access Token)
Postman is generating an access token successfully, but I cannot seem to use this authentication in my API calls. Please who knows which step I am missing - I want to handle everything in Postman.
urls.py
urlpatterns = [
path('', Home.as_view(), name='home'),
path('admin/', admin.site.urls),
path('accounts/', include(api_urls, namespace='api')),
path('accounts/login/', GoogleLogin.as_view(), name='google_login'),
path('accounts/', include('rest_framework.urls')),
]
views.py
class GoogleLogin(SocialLoginView):
adapter_class = GoogleOAuth2Adapter
callback_url = 'http://localhost:8080/accounts/google/login/callback/'
client_class = OAuth2Client
On calling an API endpoint, I get an invalid token error:
If I however visit the Google Login view in my RestFramework UI (in my case http://localhost:8080/accounts/login), I get an endpoint to make a POST, and on making a POST request, a key is generated. Only this key (if used as a Bearer token) works in my API calls.
How can I authenticate on Google, and make my API calls independent of the DRF UI?
Callback URL has been configured on my Google Developer Client.
PS: I feel the answer is in step 6 of the documentation, but I am unable to figure out how to do this in Postman
POST code or token to specified URL(/dj-rest-auth/google/)
What I did here is from postman go to headers then put Authorization = Token youraccesskey
which in your case Authorization = Token ef057......
Hope it helps

Redirect after login using JWT authentication

Im using this library django-rest-framework-simplejwt and want to
I want to be able to redirect to the endpoint after successfully obtaining a token.
I have a standard implementation of getting a token taken from the documentation
from rest_framework_simplejwt import views as jwt_views
urlpatterns = [
path('api/token/', jwt_views.TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', jwt_views.TokenRefreshView.as_view(), name='token_refresh'),
]
Is there any way to change the operation of the TokenObtainPairView function to redirect to the endpoint?

unable to make a successful call from android using retrofit with csrf token

I'm new to django and got struck with csrf tokens. I'm making a post request from android using retrofit to my django server which is using csrf protection. I had obtained the csrf token by making a get request first and then I'm passing this csrftoken from the body of POST request. However, my server is showing 'CSRF cookie not set' error. The server is responding well to the calls from POSTMAN but when I make calls from android, I get this error. I think there is some simple thing I'm missing, but I'm not able to figure it out.
Session based authorization is usually used in web-apps. In case of android apps which are backed by API.
So rather than you can do Token Based Authorization using rest_framework in Django.
In your settings.py
INSTALLED_APPS = [
...
'rest_framework',
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication', # <-- And here
],
}
Now migrate the migrations to the database.
python manage.py migrate
Run this command to generate token for the specific user.
python manage.py drf_create_token <username>
Now add this line to urls.py.
from rest_framework.authtoken.views import obtain_auth_token
urlpatterns = [
#Some other urls.
path('api-token-auth/', obtain_auth_token, name='api_token_auth'),
]
Using this you can obtain token for any user by using its username & password by just passing them in request body.
So this will be our protected api. Add this class based view in your views.py
from rest_framework.permissions import IsAuthenticated,AllowAny # <-- Here
from rest_framework.views import APIView
from rest_framework.response import Response
class DemoData(APIView):
permission_classes = (IsAuthenticated,)
def post(self, request):
content = {'data': 'Hello, World!'}
return Response(content)
Now pass a header with the api name as 'Authorization' & value be like something 'Token 5a2b846d267f68be68185944935d1367c885f360'
This is how we implement Token Authentication/Authorization in Django.
For more info, click here to see official documentation.

Authentication credentials were not provided with Django Rest Framework JWT

I am having trouble implementing token authentication with JWT in the Django rest framework with a Typscript frontend. I'm getting
{detail: "Authentication credentials were not provided."}
with my API call via Typescript, which is:
readonly BASE_URL = 'http://127.0.0.1:8000/'
api_url = this.BASE_URL + 'items/'
auth_url = this.BASE_URL + "api-token-auth/"
getItemsService(token) {
const headers = new HttpHeaders()
headers.append('Content-Type', 'application/json')
headers.append('Authorization', 'JWT ' + token.token)
return this.http.get(this.api_url, {headers: headers})
}
Logging in works fine. It's when I try to load the items that I have issues.
Here's my Django code:
views.py
from rest_framework import generics
from .models import Item
from .serializers import ItemSerializer
class ItemList(generics.ListCreateAPIView):
queryset = Item.objects.all()
serializer_class = ItemSerializer
class ItemDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Item.objects.all()
serializer_class = ItemSerializer
items/urls.py
from django.urls import path
from .views import ItemList, ItemDetail
urlpatterns = [
path('', ItemList.as_view()),
path('<int:pk>/', ItemDetail.as_view()),
]
project/urls.py
from django.contrib import admin
from django.urls import include, path
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
path('items/', include('groceries.urls')),
path('admin/', admin.site.urls),
path('api-auth/', include('rest_framework.urls')),
path('api-token-auth/', obtain_jwt_token),
]
settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
),
}
I thought the issue would have to be with Django, but I am able to get what I expect with
curl -H "Authorization: JWT <token>" http://localhost:8000/items/
If my backend was not set up correctly, this wouldn't work. So it must be my frontend code.
Based on what you described, It may be a CORS issue. Because you have access to your api endpoint via curl command. But not with browser.
Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell a browser to let a web application running at one origin (domain) have permission to access selected resources from a server at a different origin. A web application makes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, and port) than its own origin.
I checked your Angular typescript code, It seems fine. I suggest to follow below instructions in your django project and see how it goes:
1) install it for pip via pip install django-cors-headers command.
2) In settings.py file, add this app to your installed apps:
INSTALLED_APPS = (
...
'corsheaders',
...
)
3) You will also need to add a middleware class to listen in on responses:
MIDDLEWARE = [ # Or MIDDLEWARE_CLASSES on Django < 1.10
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]
remember CorsMiddleware should be placed as high as possible.
4) Add this line to your settings.py file.
CORS_ORIGIN_ALLOW_ALL = True
for full documentation refer to django-cors-headers.

Need clarity on using django-rest-framework-jwt with django-rest-auth for social login

I am able to receive a facebook authentication access_token from django-rest-auth by following their instructions in their docs, but it doesn't look like it's a JWT token generated by django-rest-framework-jwt.
I did set REST_USE_JWT = True in settings.py. That's all I've done, I'm not sure if there's anything else I need to do to ensure that the token is being generated by JWT.
I set up an endpoint to verify a jwt token like so:
from rest_framework_jwt.views import obtain_jwt_token, verify_jwt_token
urlpatterns = [
url(r'^api/token-verify/', verify_jwt_token),
]
that's how I'm testing if the access token received by this endpoint
url(r'^rest-auth/facebook/$', views.FacebookLogin.as_view(), name='fb_login'),
is a valid JWT token. When I try to verify the token I get an error Error decoding signature.
On a side note, I noticed when I try to do a POST request to rest-auth/facebook/ API endpoint twice using the same access_token returned by a Facebook login I am receiving a 403 Forbidden from django.
Can someone please explain a bit how to make JWT work with django-rest-auth?