How to get all user information from auth user in django rest framework? - django-rest-framework

I am using Django sample JWT and I already set up for the login user. let say now I have a login user token. but at the client-side, we still need to show like user name, user image, and email address. How to get this information in the client-side?
I created a new method that will return current login user at backend=>
#get token for login user
#action(detail=False, methods=['get'])
def get_current_user(self,request):
data = {}
data["username"] = request.user.username
.
.
.
return Response({format(data)})
It's the correct way? or Can I serialize request.user and return directly? Is there any serializer for Auth-User? I am stuck there. Thanks.

If you are going for a basic retrieve of the user,you should create a serializer for the user and a generic view which uses that serializer to return the data

Related

Django RF simplejwt returns only token, not user object

I have React app and a Redux store. I am working on an authentication now. My backend is on Django RF and for JWT auth I use a simplejwt lib. The thing is, that this lib has an "out of the box" view (/token) that returns a JWT token on success.
The problem is that I need to have a user object in my app upon successful authentication. So when the user logs in it returns a token only. But I need to redirect the user to their page if logged in.
I sure can override this /token view and return whatever object I want, but why is this implemented this way right now?
Looks like there is no other way that to override validate() method in serializers.py like this:
class UserTokenObtainPairSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
data = {
'token': super().validate(attrs),
'id': self.user.id,
'email': self.user.email,
'name': self.user.name,
}
return data

Getting user details from access token in Django rest framework -simple JWT

I am using React and Django rest framework for a project. I use Django rest framework simple JWT for authentication. Now, I want to display the username in the navbar after the user logs in. So, is there a way in simple JWT for returning user details from the access token generated after authentication, just like Djoser returns user credentials when supplied the access token?
Sorry if this question is silly but I was not able to find a solution to this anywhere.
if you want to obtain the information of the owner of the token you can consult it in REQUEST.
class ViewProtect(APIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def post(self, request, format=None):
token_user_email = request.user.email
token_user_username = request.user.username
pass
About the backend, basically I use this library
from restframework_simplejwt.tokens import AccessToken
The function AccessToken() take as input the string access_token_str and return the object access_token_obj.
To get the user_id, you can use the instruction
user_id=access_token_obj['user_id'].
In the following example I have created the function
get_user_from_access_token_in_django_rest_framework_simplejwt().
This function is just a wrapper around AccessToken()
Full code:
#Path current file
#/blabla/django/project004/core/view.py
from restframework_simplejwt.tokens import AccessToken
from django.contrib.auth.models import User
#Example data.
#access_token_str = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiY29sZF9zdHVmZiI6IuKYgyIsImV4cCI6MTIzNDU2LCJqdGkiOiJmZDJmOWQ1ZTFhN2M0MmU4OTQ5MzVlMzYyYmNhOGJjYSJ9.NHlztMGER7UADHZJlxNG0WSi22a2KaYSfd1S-AuT7lU'
def get_user_from_access_token_in_django_rest_framework_simplejwt(access_token_str):
access_token_obj = AccessToken(access_token_str)
user_id=access_token_obj['user_id']
user=User.objects.get(id=user_id)
print('user_id: ', user_id )
print('user: ', user)
print('user.id: ', user.id )
content = {'user_id': user_id, 'user':user, 'user.id':user.id}
return Response(content)
Credits:
#davesque;
https://github.com/jazzband/djangorestframework-simplejwt/issues/140
Update.
The string access_token_str I write in the file is just an example. You should pass it as argument.
Here's how I've done it.
On Django, I followed the steps described on this page in order to add the user's name inside the JWT token : https://django-rest-framework-simplejwt.readthedocs.io/en/latest/customizing_token_claims.html
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
#classmethod
def get_token(cls, user):
token = super().get_token(user)
# Add name to token
token['name'] = user.get_full_name()
# You can add other information into the token here
return token
class MyTokenObtainPairView(TokenObtainPairView):
serializer_class = MyTokenObtainPairSerializer
Then, I updated my urls.py to use the custom view:
path('token/', MyTokenObtainPairView.as_view(), name='token_obtain_pair'),
Finally, in my Vue.js application, I installed the jwt-decode package and used it like this:
const token = localStorage.getItem('access_token');
const decoded = jwt_decode(token);
console.log(decoded)
// decoded.name contains the user's full name
Note that I store the access token in the local storage beforehand.

"Method \"POST\" not allowed." Django REST

I am new to django rest framework. I have an api to get corresponding token for each user. The method defined to access token is
class ObtainAuthToken(APIView):
def post(self, request):
user = authenticate(
username=request.data['username'], password=request.data['password'])
if user:
token, created = Token.objects.get_or_create(user=user)
return Response({'token': token.key, 'user': UserSerializer(user).data})
return Response('Invalid username or password', status=status.HTTP_400_BAD_REQUEST)
and in urls.py i have
url(r'^login/$',ObtainAuthToken, name='login')
But while logging in a user, i am getting the response as
{
"detail": "Method \"POST\" not allowed."
}
Where did i went wrong?
First of all - I see that you used the django-rest-auth tag. Are you actually using rest auth? If not - you should definitely consider doing it as it provides a ton of auth functionality out of the box.
As to your question, you forgot to call as_view() on ObtainAuthToken in your url conf. Change it like so and tell me if it works:
url(r'^login/$', ObtainAuthToken.as_view(), name='login')
You have the wrong indentation in your code. The post method needs to be inside the ObtainAuthToken(APIView) class. Right now is defined as a standalone function.

How to add additional data to object Auth in Laravel 5.3?

There is default object Auth in Laravel after authification.
It contents data about current user from table Users.
How can I add the additional data to this object from other related table?
Edit:
So, if I am right, the object Auth is created when user is authenticated. In this moment I need to fill object by additional data.
I presume you want to retrieve a user in a controller and return it as a response, maybe json? or not, it's doesn't really matter. here what you could do
public function getUser()
{
$user = auth()->user();
$user->load('relationName');
$user->load('anotherRelationName');
}

Laravel crsftoken routing

I have some troubles with the crsf_token() in laravel. I create a URL to send to the user with the token and if they click this unique link the post will set the token to NULL.
Here my sample code:
//get token from database
$getDataUserToken = $subject->lists('token');
// send the token to email user (unique token)
#foreach ($token as $toke){{ URL::to('/extend/verify', array($toke)) }}#endforeach
This code will generate: www.example.com/extend/verify/1234123TOKENHERE2313213123
Now I want if user clicks on this link that the token sets to null.
I tried this:
Route::get('/extend/verify/{$toke}', 'SubjectController#confirm');
But when I do this I get an error that says: throw new NotFoundHttpException;
So the url is not found and I don't know how to get that url token and send it to my controller to do some stuff with that.
the laravel route parameters not use "$".
this is a correct use:
Route::get('/extend/verify/{toke}', 'SubjectController#confirm');

Resources