get auth token using dj-rest-auth when user logged in - django

Previously I was using django-rest-auth package and I was getting the auth token when user log in in response response.data.key and this auth token or key was working fine with the api calls as authentication auth
Previously for django-rest-auth:
"/rest-auth/login/"
was getting the response.data.key as auth token and that was working
I have stored in the cookie for later use
.get("/rest-auth/user/", {
headers: {
"Content-Type": "application/json",
Authorization: "Token " + response.data.key + "",
},
})
It was working to get info on user and also was working when used in other api calls by setting it in
Authorization: "Token " + response.data.key + ""
But now, I'm using dj-rest-auth package instead of django-rest-auth and shifted my urls to
/dj-rest-auth/login
and I'm not getting any key or auth token that I can use for authorization in header.
.get("/dj-rest-auth/user/", {
headers: {
"Content-Type": "application/json",
Authorization: "Token " + response.data.? + "",
},
})
It's not working because now I'm getting access_token , refresh_token and user info. I tried to use access_token and refresh_token for authorization in header but it's not working because I'm not getting key or auth token in response when user log in
Note: django-rest-auth is no more maintained and dj-rest-auth is forked from the previous one and have more functions (this is the reason why I'm switching)
How to get auth token or key by using dj-rest-auth package so that I can use it in the header of API calls for authorization?

Check that you don't have an REST_USE_JWT = True in your settings. That setting will enable JWT authentication scheme instead of a (default) token-based.

In django-rest-auth you get the key from a GET request, but according to dj-rest-auth's documentation, you get the token key as a response when you make a post request to /dj-rest-auth/login/.
When you make a POST request to /dj-rest-auth/login/, you can access the key at response.data. But now you need to store it so you can use it in your get requests.
I recommend checking out this question's answers to learn more about storing tokens. How you choose to do this will depend on how to the frontend of your application is built, as the javascript needs access to the token key.
I know I'm late to answer this, but hopefully I can help someone other folks who find this.

Related

Getting the OAuth Token from FedEx to use for Track API

I'm trying to get the OAuth Token to get auth access to some of the FedEx APIs ( like Track API for tracking shipments ), but I get a
401 (NOT.AUTHORIZED.ERROR -> "The given client credentials were not valid. Please modify your request and try again") error.
(At the moment, I'm using Postman to try and test the APIs.)
Here is the url I'm using, found provided by FedEx:
https://apis-sandbox.fedex.com/oauth/token
I've followed ( to my understanding ) how the body and headers should be set:
Headers: Content-Type: application/x-www-form-urlencoded
Body: x-www-form-urlencoded (Postman option):
grant_type: client_crendentials
client_id: ***PROJECT_API_KEY
client_secret: ***PROJECT_SECRET KEY
After sending, I only get the error message above. I checked / doubled-checked my API keys, but I can't seem to get it to go through.
Any ideas?
postman settings:
POST - URL https://apis-sandbox.fedex.com/oauth/token
Headers - Content-Type: application/x-www-form-urlencoded
Body - x-www-form-urlencoded:
grant_type: client_credentials
client_id: *******
client_secret: *******
(information gotten from https://developer.fedex.com/api/en-us/catalog/authorization/v1/docs.html)
The sandbox API credentials are not immediately usable when creating a new account. It took >1 hour for me to get a registration complete email from FedEx after which the sandbox credentials became valid.

Django REST social login with dj_rest_auth does not authenticate the user

I am building an application. The client is built with Next.js and the backend with Django and Django REST framework.
In this application, I would like to have social login.
So far, my situation is this.
I have set up the OAuth on the Google dashboard
On the client, I am using next-auth - The client is successfully calling Google and getting an access token from there.
On the client, the callback that runs after getting the access token from Google makes a call my Django API.
I have set up the backend with dj_rest_auth - My settings are almost identical to the ones described here.
Once the client callback runs and calls my Django API with the access token from Google, I successfully get on the client an access token and a refresh token.
If it is a new user loggin in the first time, a new user is created in Djangos DB
const response = await fetch(`${djangoAPIurl}/api/social/login/google/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
access_token: accessToken,
id_token: idToken
})
});
const data = await response.json();
const { access_token, refresh_token } = data;
Both access_token and refresh_token are defined and appear to be valid tokens.
So far, everything happens as expected. My issue appears after this point.
In my api, I have another view defined.
#api_view(['GET'])
#authentication_classes([SessionAuthentication, BasicAuthentication, TokenAuthentication])
#permission_classes([IsAuthenticated])
def test_view(request):
current_user = request.user
print('current_user.auth: ', current_user.is_authenticated)
response = JsonResponse({"received": True})
return response
From my client, I am attempting to call this view in the following way.
const response = await fetch(`${djangoAPIurl}/api/test/test_view/`, {
headers: new Headers({
Authorization: `Bearer ${session.accessToken}`
})
});
The header is constructed correctly, with session.accessToken being the value I got from the api/social/login/google/ call and the request is routed correctly, however, it fails with Forbidden 403 because the user is not authenticated. I have removed the authentication and permission decrators and the request ends up being processed by the view, and there, upon inspection of the user, it is an Anonymous user. I have also tried changing Bearer to Token, to no avail.
Do you have any advice what I might be doing wrong or missing? Have I completely missunderstood how to use the token I get back from api/social/login/google/? All advice is much appreicated!
I think this is because your secret for hashing JWTS on the client side and server side is not same. Next-Auth automatically creates a secret key for hashing jwt's and dj_rest_auth does the same, unless you explicitly tell them both to use the same secret for hashing jwts. I'm a bit late to answer this, but Hope this will help future people😁😁.

How does one keep a user logged in with Django Rest Framework?

I'm new to Django coming from the Firebase world, where authentication and keeping a user logged in is super easy.
In learning Django (Rest Framework) I came to find out that you can log in a user, get a token and save the token in Cookies to reuse is next time that same user goes into the website. Is this the best way to keep a user logged in?
So far, I can log a user in, get their token and some additional info, but I'm not sure how to prevent this from happening over and over again. I'd like to know how to keep the user logged in.
Also, whenever the user gets back on the browser, do I place a POST request to get their own information (if needed to display on the screen)? Always?
I'm very confused as to how authentication/logging in works.
An usual way to handle this problem is to use Jwt auth.
You will issue a short lived token alongside a long lived refresh token to your consumer.
https://github.com/jpadilla/django-rest-framework-jwt
On your frontend side you can implement an automatic refresh mechanism when the token expire.
Example with React: https://medium.com/#monkov/react-using-axios-interceptor-for-token-refreshing-1477a4d5fc26
On browser side, it's depend. For example with single page app, you can fetch info only one and store them in a store.
For multi page app, you could still use cookie or local storage to persist data.
Each Request is anonymous/new, even after you login.
Why I keep loggedin?
Once you logged in, server usually reuturn a token and save it in your local browser. Next time you send request, you can add the token in your request. Then server will know it is still the same user.
What is token?
There a many kinds of token: session token, jwt, basic token...
Token is a string of your identity, and jwt(JSON Web Tokens) is one of the most popular authentication(CORS) solution. This is how original jwt looks like:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
And this is how actual jwt data looks like:
# HEADER:ALGORITHM
{
"alg": "HS256",
"typ": "JWT"
}
# PAYLOAD:DATA
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
# VERIFY SIGNATURE
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)
Where do I keep token
Token is storage in your local cookies. For each request, you can get token from local cookies and add to request head. For example, in React:
import Cookies from "universal-cookie"
localCookies = new Cookies();
...
..
fetch(`/api/logs/:id`, {
headers: {
'Content-Type': 'application/json',
'Authorization': 'JWT ' + localCookies.get('token'),
}
})
...
..

How to authenticate request in Django-rest-auth?

I am trying to integrate django-rest-auth package in my web application. So far i am able to register users, send password reset email and login using the API provided by django-rest-auth package.
Now when i send a login request, it returns "token" upon successful authentication.
How do i send authentication token in further requests? For example, i am trying to fetch user using GET /rest-auth/user but it is giving me a response Authentication credentials not provided. I have tried passing token via HTTP Basic Authentication (base64 encode token as username and leave password as empty). I am still not able to work.
Anyone knows how i am supposed to pass this token in requests?
If you want to use the Token Authentication you have to set the Authorization HTTP header. From the docs:
For clients to authenticate, the token key should be included in the Authorization HTTP header. The key should be prefixed by the string literal "Token", with whitespace separating the two strings. For example:
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
In an ajax call you can a header like this:
$.ajax({
type: 'POST',
url: url,
beforeSend: function (request)
{
request.setRequestHeader("Authorization", "Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b");
},
});
HI
You need to send token in headers
$.ajax({
type:"POST",
beforeSend: function (request)
{
request.setRequestHeader("Authority", 'Bearer 33a95862173cc0565fe502eb062b2e7c67e23a3a');
},
and in django code use
user = request.user
if user:
return "User token verified"
elif :
return "User token not verified"
in django automaticaly find token in headers and using token fetch user data.

Django Rest Framework Postman Token Authentication

I am using Django Rest Framework Token authentication and if i do curl http://localhost:8000/api/v1/users/?format=json -H 'Authorization: Token 0a813fdcd3f8846d6fa376f2592bbc678b0b8e85' everything works fine.
But when i try to achieve that with Postman chrome client it nothing happens. What am i doing wrong??
You are setting the header to Authorization: Token when it really should just be Authorization. The header is actually just Authorization, but the value is Token [token_string], where [token_string] is the authorization token that you have obtained.
For the new version of postman it is necessary to choose Auth 2 type authentication in the left panel, then in the right panel, specify the DRf key which is "Token" and in the value the token itself.
In addition to the above answer, make sure to enable "Follow Authorization header" under setting (See below screenshot)
After Specifying Authorization and Token value try to add the token in an environment so that every time you don't have to copy the token value.
After get access token from http://127.0.0.1:8000/accounts/login/
such this :
{
"email": "user#example.com",
"tokens": {
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTY2NjI2NTAxMSwiaWF0IjoxNjY2MTc4NjExLCJqdGkiOiJjZWM3MzJmNDZkMGE0MTNjOTE3ODM5ZGYxNzRiNzMxZCIsInVzZXJfaWQiOjcwfQ.5Rd25s6msp72IHyU1BxE4ym24YIEbhyFsBdUztGXz0I",
"access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjY2MjY1MDExLCJpYXQiOjE2NjYxNzg2MTEsImp0aSI6IjgyOWFmZGE5MWY2ODRhNDZhMDllZGMzMmI0NmY0Mzg5IiwidXNlcl9pZCI6NzB9.TYhi0INai293ljc5zBk59Hwet-m9a1Mc1CtA56BEE_8"
},
"id": 70
}
copy content of "access" key in response, then in post man in Headers add new item by key : Authorization and value such this:
Bearer eyJ0eXAi....
that eyJ0eXAi.... is value of access key.
then send the request.