I want to destroy auth token when user get logged out. User get logged out successfully in the view that I have provided.But I need to destroy token when user get logout.
views.py
class UserLoginViewSet(viewsets.ViewSet):
def create(self,request):
try:
data=request.data
email=data.get('email')
password=data.get('password')
date_of_birth=data.get('date_of_birth')
if not all([email,password,date_of_birth]):
raise Exception('all fields are mandetory')
user=authenticate(username=email,password=password)
if user is not None:
token=generate_token()
user_info=MyUser.objects.get(email=email)
data=({
'email':user_info.email,
'password':user_info.password,
#'data_of_birth':user_info.data_of_birth
})
return Response({"message": "You are successfully logged in",
"user_info":data,"token": token, "success": True},status=status.HTTP_200_OK)
else :
raise Exception('not authorised')
except Exception as error:
traceback.print_exc()
return Response({"message": str(error), "success": False}, status=status.HTTP_200_OK)
def delete(self,request):
logout(request)
return Response({'successfull':True})```
#my user is logging out correctly,but i want to doi this by deleting token
you can do like this
class UserLoginViewSet(viewsets.ViewSet):
def create(self,request):
try:
data=request.data
email=data.get('email')
password=data.get('password')
date_of_birth=data.get('date_of_birth')
if not all([email,password,date_of_birth]):
raise Exception('all fields are mandetory')
user=authenticate(username=email,password=password)
if user is not None:
token=generate_token()
user_info=MyUser.objects.get(email=email)
data=({
'email':user_info.email,
'password':user_info.password,
#'data_of_birth':user_info.data_of_birth
})
return Response({"message": "You are successfully logged in",
"user_info":data,"token": token, "success": True},status=status.HTTP_200_OK)
else :
raise Exception('not authorised')
except Exception as error:
traceback.print_exc()
return Response({"message": str(error), "success": False}, status=status.HTTP_200_OK)
class LogoutView(APIView):
permission_classes = (permissions.IsAuthenticated,)
def get(self, request):
request.user.auth_token.delete()
logout(request)
return Response({"message": "success", 'code': status.HTTP_200_OK, 'detail': "logout success"})
In app urls.py add new url:
path('logout/',LogoutView.as_view()),
Related
I want to restrict multiple user logins like when a user tries to login again i want to give him a error saying you already have a active session
This is how i am doing it right now
my middleware.py
class MySessionMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
print(request.user.is_authenticated)
if request.user.is_authenticated:
print('here2')
try:
user = LoggedInUser.objects.create(user=request.user)
except:
user = LoggedInUser.objects.filter(user=request.user).first()
print(type(user))
if not request.session.session_key:
request.session.save()
prev_session_key = request.user.logged_in_user.session_key
print(prev_session_key)
if prev_session_key:
print(prev_session_key)
print(request.session.session_key)
print('here5')
#check whether old key is same as current
print('here inside user.session_key')
if prev_session_key != request.session.session_key:
return JsonResponse("you already have a active session kindly logout from that",
status=400, safe=False)
user.session_key = request.session.session_key
user.save()
return response
my models.py
class LoggedInUser(models.Model):
user = models.OneToOneField(User, related_name='logged_in_user', on_delete =models.CASCADE, null=True, blank=True)
session_key = models.CharField(max_length=32, null=True, blank=True)
But this approach is not working as previous session key always comes out to be None , please suggest changes in my approach , i tried many solutions but they didnt work
my login view
class UserLoginView(generics.RetrieveAPIView):
"""
View for a user to login through 1FA.
The view provides a post request that accepts a email and password.
Returns a jwt token as a response to authenticated user.
"""
permission_classes = ()
serializer_class = UserLoginSerializer
def post(self, request):
"""
POST request to login a user.
"""
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
response = {
"success": "True",
"message": "User logged in successfully",
"token": serializer.validated_data["tokens"],
"user_name": serializer.validated_data["user_name"],
}
status_code = status.HTTP_200_OK
return Response(response, status=status_code)
Remove your logic from session middleware, add them in login view.
class UserLoginView(generics.RetrieveAPIView):
"""
View for a user to login through 1FA.
The view provides a post request that accepts a email and password.
Returns a jwt token as a response to authenticated user.
"""
permission_classes = ()
serializer_class = UserLoginSerializer
def post(self, request):
"""
POST request to login a user.
"""
if (request.user.is_authenticated):
response = {
"success": "False",
"message": "User already logged in!",
}
return Response(response, status=400)
else:
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
response = {
"success": "True",
"message": "User logged in successfully",
"token": serializer.validated_data["tokens"],
"user_name": serializer.validated_data["user_name"],
}
status_code = status.HTTP_200_OK
return Response(response, status=status_code)
I am using django-rest-knox, when I logout using knox_views.LogoutAllView.as_view(), it gives me this error:
"detail": "Authentication credentials were not provided."
Note: I am using a custom user model(AbstarctUser and BaseUserManager)
Here is serializers.py:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'email','birth_date','first_name','last_name')
# there is a registerserializer too
class LoginSerializer(serializers.Serializer):
email = serializers.EmailField()
password = serializers.CharField()
def validate(self, data):
user = authenticate(**data)
if user and user.is_active:
return user
raise serializers.ValidationError("Incorrect Credentials")
and here's views.py:
class LoginView(generics.GenericAPIView):
serializer_class = LoginSerializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user= serializer.validated_data
return Response({
"user": UserSerializer(user, context=self.get_serializer_context()).data,
"token": AuthToken.objects.create(user)[1]
})
class RegisterAPI(generics.GenericAPIView):
serializer_class = RegisterSerializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.save()
return Response({
"user": UserSerializer(user, context=self.get_serializer_context()).data,
"token": AuthToken.objects.create(user)[1]
})
From the docs:
This view accepts only a post request with an empty body. It responds to Knox Token Authentication. On a successful request, the token used to authenticate, and all other tokens registered to the same User account, are deleted from the system and can no longer be used to authenticate.
This means you still need to use the token you generated upon authentication with the logout endpoint.
i am new in django, i require login with user and password or facebook, i am using rest framework for api endpoints. ¿How i can do it?
i try with:
django-rest-framework-social-oauth2 but don't work for my because i needs save additional info from user after first enter.
I expect have 2 endpoint one sending user and password and another sending facebook auth token
Here's sample code for user login for Django Rest Framework:
class Login(APIView):
#csrf_exempt
def dispatch(self, *args, **kwargs):
return super(Login, self).dispatch(*args, **kwargs)
#staticmethod
def post(request):
request_data = JSONParser().parse(request)
if 'email' in request_data and 'password' in request_data:
try:
validate_email(request_data['email'])
except ValidationError:
return JsonResponse({'result': 'E-mail is invalid'}, status=400)
user = authenticate(email=request_data['email'], password=request_data['password'])
if user is not None:
if user.is_active:
try:
token = Token.objects.get(user=user)
except Token.DoesNotExist:
token = Token.objects.create(user=user)
return JsonResponse({'result': 'success', 'token': token.key, 'id': user.id}, status=200)
return JsonResponse({'result': 'E-mail or password is incorrect'}, status=400)
return JsonResponse({'result': 'E-mail or password is empty'}, status=400)
Here's sample for FB login code for Django Rest Framework (from my test project):
class FbLogin(APIView):
authentication_classes = (authentication.TokenAuthentication,)
permission_classes = (permissions.AllowAny,)
#csrf_exempt
def dispatch(self, *args, **kwargs):
return super(FbLogin, self).dispatch(*args, **kwargs)
#staticmethod
def post(request):
request_data = JSONParser().parse(request)
if 'access_token' in request_data:
response = requests.get(
url='https://graph.facebook.com/v2.5/me/',
params={
'access_token': request_data['access_token'],
'fields': 'email,first_name,last_name',
},
)
json_response = json.loads(response.text)
if 'error' not in json_response:
response_photo = requests.get(
url='https://graph.facebook.com/v2.5/%s/picture' % json_response['id'],
params={
'redirect': 'false',
'type': 'large',
},
)
response_photo_json = json.loads(response_photo.text)
response_friends = requests.get(
url='https://graph.facebook.com/v2.5/me/friends/',
params={
'access_token': request_data['access_token'],
'limit': 300,
},
)
generated_password = get_random_string(10, '0123456789abcdefghijklmnopqrstuvwxyz')
try:
json_response_email = json_response['email']
except:
first_name = json_response['first_name'].lower()
last_name = json_response['last_name'].lower()
id = json_response['id']
json_response_email = first_name + last_name + id + '#facebook.com'
try:
current_user = User.objects.get(email=json_response_email)
current_user.set_password(generated_password)
current_user.save()
except User.DoesNotExist:
new_user = User.objects.create_user(email=json_response_email,
password=generated_password)
new_user.provider_id = json_response['id']
new_user.provider_type = 'facebook'
if 'first_name' in json_response:
new_user.first_name = json_response['first_name']
if 'last_name' in json_response:
new_user.last_name = json_response['last_name']
new_user.save()
photo_name = urlparse(response_photo_json['data']['url']).path.split('/')[-1].split('?')[-1]
photo_content = urllib.request.urlretrieve(response_photo_json['data']['url'])
new_user.profile_photo.save(photo_name, File(open(photo_content[0], 'rb')), save=True)
user = authenticate(email=json_response_email, password=generated_password)
try:
token = Token.objects.get(user=user)
except Token.DoesNotExist:
token = Token.objects.create(user=user)
if user is not None:
if user.is_active:
fullname = json_response['first_name'] + ' ' + json_response['last_name']
return JsonResponse({'result': 'success', 'token': token.key, 'name': fullname}, status=200)
return JsonResponse({'result': 'User access token is incorrect'}, status=400)
I am trying to login to my custom LoginView using curl request but I a getting the following error:
{"detail":"Authentication credentials were not provided."}.
But the default login API(api-token-auth) is working fine.
LoginView:
class LoginView(views.APIView):
def post(self, request, format=None):
data = json.loads(request.body)
email = data.get('email', None)
password = data.get('password', None)
account = authenticate(email=email, password=password)
if account is not None:
if account.is_active:
login(request, account)
token = get_jwt_token(account)
return Response(token)
else:
return Response({
'status': 'Unauthorized',
'message': 'This account has been disabled.'
}, status=status.HTTP_401_UNAUTHORIZED)
else:
return Response({
'status': 'Unauthorized',
'message': 'Username/password combination invalid.'
}, status=status.HTTP_401_UNAUTHORIZED)
using the tastypie API and implementing some functionality for the user resource (following this example code: How can I login to django using tastypie), I wonder how the authenticated user is deposited or how I can access it in the right way. While testing the login method:
curl -u "user:pw" -H "Content-Type: application/json" -X POST --data '{"username" : "user", "password": "pw"}' http://localhost:8000/api/user/login/?format=json
everything works fine; but the logout method sees the request.user as an anonymous user. How can I pass to the logout method the right authenticated user? Thanks a lot.
Snippet from api.py
class UserResource(ModelResource):
class Meta:
queryset = AppUser.objects.all()
resource_name = 'user'
fields = ['first_name', 'last_name', 'username', 'email', 'is_staff']
allowed_methods = ['get', 'post', 'patch']
always_return_data = True
authentication = BasicAuthentication()
authorization = Authorization()
def prepend_urls(self):
params = (self._meta.resource_name, trailing_slash())
return [
url(r"^(?P<resource_name>%s)/login%s$" % params, self.wrap_view('login'), name="api_login"),
url(r"^(?P<resource_name>%s)/logout%s$" % params, self.wrap_view('logout'), name="api_login")
]
def login(self, request, **kwargs):
"""
Authenticate a user, create a CSRF token for them, and return the user object as JSON.
"""
self.method_check(request, allowed=['post'])
data = self.deserialize(request, request.raw_post_data, format=request.META.get('CONTENT_TYPE', 'application/json'))
username = data.get('username', '')
password = data.get('password', '')
if username == '' or password == '':
return self.create_response(request, {
'success': False,
'error_message': 'Missing username or password'
})
user = authenticate(username=username, password=password)
if user:
if user.is_active:
login(request, user)
response = self.create_response(request, {
'success': True,
'username': user.username
})
response.set_cookie("csrftoken", get_new_csrf_key())
return response
else:
return self.create_response(request, {
'success': False,
'reason': 'disabled',
}, HttpForbidden )
else:
return self.create_response(request, {
'success': False,
'error_message': 'Incorrect username or password'
})
def logout(self, request, **kwargs):
"""
Attempt to log a user out, and return success status.
"""
self.method_check(request, allowed=['get'])
if request.user and request.user.is_authenticated():
logout(request)
return self.create_response(request, { 'success': True })
else:
return self.create_response(request, { 'success': False, 'error_message': 'You are not authenticated, %s' % request.user.is_authenticated() })
If you're making your own custom tastypie URLs you need to call the tastypie authentication yourself before the request.user object is populated correctly.
def logout(self, request, **kwargs):
"""
Attempt to log a user out, and return success status.
"""
self.method_check(request, allowed=['get'])
# Run tastypie's BasicAuthentication
self.is_authenticated(request)
if request.user and request.user.is_authenticated():
logout(request)
return self.create_response(request, { 'success': True })
else:
return self.create_response(request, { 'success': False, 'error_message': 'You are not authenticated, %s' % request.user.is_authenticated() })