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() })
Related
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()),
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)
Good day!
I'm new here and a beginner in django and I want to create registration of user with instant profile upon successful registration.
resources.py
class AccountResource(ModelResource):
class Meta:
proxy=True
authorization= DjangoAuthorization()
# authentication = AUTHENTICATION
queryset = User.objects.all()
list_allowed_methods = ['get', 'post']
resource_name = 'account'
fields = ['username','password','email']
def prepend_urls(self):
return [
url(r"^(?P<resource_name>%s)/register%s$" %
(self._meta.resource_name, trailing_slash()),
self.wrap_view('register'), name="api_register"),
url(r"^(?P<resource_name>%s)/login%s$" %
(self._meta.resource_name, trailing_slash()),
self.wrap_view('login'), name="api_login"),
url(r"^(?P<resource_name>%s)/logout%s$" %
(self._meta.resource_name, trailing_slash()),
self.wrap_view('logout'), name="api_logout"),
url(r"^(?P<resource_name>%s)/activate%s$" %
(self._meta.resource_name, trailing_slash()),
self.wrap_view('activate'), name="api_activate"),
]
def activate(self, request, **kwargs):
data = self.deserialize(request, request.body,format=request.META.get('CONTENT_TYPE', 'application/json'))
activation_key = data.get('activation_key', '')
activated_user = RegistrationProfile.objects.activate_user(activation_key)
if activated_user:
return self.create_response(request, {
'success': True,
'username': activated_user
})
else:
return self.create_response(request, {
'success': False,
'reason': 'already activated or user activation not exist',
}, HttpUnauthorized )
def register(self, request, **kwargs):
data = self.deserialize(request, request.body, format=request.META.get('CONTENT_TYPE', 'application/json'))
username = data.get('username', '')
password = data.get('password', '')
email = data.get('email', '')
RegistrationProfile.objects.create_inactive_user(username, email, password,'',send_email=True)
new_user = authenticate(username=username, password=password)
if new_user:
return self.create_response(request, {
'success': True
})
else:
return self.create_response(request, {
'success': False,
'reason': 'incorrect',
}, HttpUnauthorized )
def default_group(sender, instance, created, **kwargs):
if created:
instance.groups.add(Group.objects.get(name='Member'))
post_save.connect(default_group, sender=User)
Above code use to register, activate etc. using url POST with raw data. What I what to know if there's a way to create a "Profile" after user have been created using register or after the user have been activated. Any response or concern are mostly appreciated. Thanks in advance.
OMG I also answer my question. I think it's already answered(duplicate) but I still show for other with same problem as mine.
something/Models.py
from django.db.models.signals import post_save
class Profile(models.Model):
(blah blah blah) ...
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
my problem earlier is I didn't DROP my DATABASE(because I'm afraid that it cause bigger problem). I don't know but once i do that it's work like a charm(now my problem is I need to re-encode my data XD ).
I am currently working on a project which requires Api, i choose Tastypie and implemented the following. I want to use tastypie's default features like ApiKeyAuthentication, DjangoAuthorization etc... in my code
class UserResource(ModelResource):
class Meta:
queryset = User.objects.all()`enter code here`
fields = ['first_name', 'last_name', 'email']
allowed_methods = ['get', 'post']
resource_name = 'user'
def override_urls(self):
return [
url(r"^(?P<resource_name>%s)/login%s$" %
(self._meta.resource_name, trailing_slash()),
self.wrap_view('login'), name="api_login"),
url(r'^(?P<resource_name>%s)/logout%s$' %
(self._meta.resource_name, trailing_slash()),
self.wrap_view('logout'), name='api_logout'),
]
def login(self, request, **kwargs):
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', '')
user = authenticate(username=username, password=password)
if user:
if user.is_active:
login(request, user)
return self.create_response(request, {
'success': True
})
else:
return self.create_response(request, {
'success': False,
'reason': 'disabled',
}, HttpForbidden )
else:
return self.create_response(request, {
'success': False,
'reason': 'incorrect',
}, HttpUnauthorized )
def logout(self, request, **kwargs):
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 }, HttpUnauthorized)
Use Code Below
from django.contrib.auth.models import User
from tastypie.authentication import ApiKeyAuthentication
from tastypie.authorization import DjangoAuthorization
from tastypie.resources import ModelResource
class UserResource(ModelResource):
class Meta:
queryset = User.objects.all()
resource_name = 'auth/user'
excludes = ['email', 'password', 'is_superuser']
# Add it here.
authentication = ApiKeyAuthentication()
authorization = DjangoAuthorization()