Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I login to django using tastypie

Tags:

I'm trying to override is_authenticated in my custom authentication. I have something simple (to start with) like this:

class MyAuthentication(BasicAuthentication):     def __init__(self, *args, **kwargs):         super(MyAuthentication, self).__init__(*args, **kwargs)      def is_authenticated(self, request, **kwargs):         return True 

then in my ModelResource I have

class LoginUserResource(ModelResource):      class Meta:         resource_name = 'login'         queryset = User.objects.all()         excludes = ['id', 'email', 'password', 'is_staff', 'is_superuser']         list_allowed_methods = ['post']          authentication = MyAuthentication()         authorization = DjangoAuthorization() 

I keep getting a 500 error back with "error_message": "column username is not unique". I only have one username in the db and it's the user I am trying to authenticate.

Any ideas as to why it's returning this error? How would I allow an api client to login?

Thanks for the help.

like image 354
imns Avatar asked Aug 02 '12 03:08

imns


People also ask

What is Django Tastypie?

¶ Tastypie is a webservice API framework for Django. It provides a convenient, yet powerful and highly customizable, abstraction for creating REST-style interfaces. Using Tastypie With Non-ORM Data Sources. Resources.

How do I authenticate login in Django?

In a nutshell, these four commands create a new Django project named src, enter the project, create a new app, mysite, inside the src project, then create a SQLite database for the project named db. sqlite3. Also be sure to include the mysite app inside src/settings.py. INSTALLED_APPS = [ 'src', 'django.

How do I find my Django username and password?

Try using the set_password(raw_password) method to give the user a new password. Remember to call the save() method to ensure you save the change to the database.

How do I authenticate an email and password in Django?

Email authentication for Django 3.x For using email/username and password for authentication instead of the default username and password authentication, we need to override two methods of ModelBackend class: authenticate() and get_user():


2 Answers

Your approach will try to create a new user with the username that you are authenticating with. This will bubble up at the DB layer, as you've noticed, that such a user already exists.

What you want is to create a UserResource, add a method on it that users can post to and login with data passing in username/password.

from django.contrib.auth.models import User from django.contrib.auth import authenticate, login, logout from tastypie.http import HttpUnauthorized, HttpForbidden from django.conf.urls import url from tastypie.utils import trailing_slash  class UserResource(ModelResource):     class Meta:         queryset = User.objects.all()         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) 

Now you can do send a POST to http://hostname/api/user/login with data { 'username' : 'me', 'password' : 'l33t' }.

like image 65
enticedwanderer Avatar answered Sep 21 '22 15:09

enticedwanderer


This update removes security issues on the GET method. Works on Django 1.5.4.

class UserResource(ModelResource):      class Meta:         queryset = User.objects.all()         resource_name = 'user'         allowed_methods = ['post']       def prepend_urls(self):         return [             url(r"^user/login/$", self.wrap_view('login'), name="api_login"),             url(r"^user/logout/$", 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=['post'])         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) 
like image 36
ktsw Avatar answered Sep 23 '22 15:09

ktsw