How to Login to Django Using Tastypie

How can I login to django using tastypie

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' }.

tastypie - Login from mobile to Django, how do I set up with ApiKeyAuthentication

I ended up doing the following:

# ──────────────────────────────────────────────────────────────────────────────
class BaseResource(ModelResource):

# ──────────────────────────────────────
def prepend_urls(self):
try:
additional_urls = self._meta.additional_urls
except AttributeError:
additional_urls = []
return [url(r'^'+u[0]+'$', self.wrap_view(u[1]), name=u[2]) for u in additional_urls]

# ──────────────────────────────────────
def update_in_place(self, request, original_bundle, new_data):
try:
allowed_fields = self._meta.allowed_fields
except AttributeError:
allowed_fields = None
if allowed_fields and set(new_data.keys()) - set(allowed_fields):
raise BadRequest('Only alterable field(s): {}'.format(', '.join(allowed_fields)))
return super(ProfileResource, self).update_in_place(request, original_bundle, new_data)

# ──────────────────────────────────────
class Meta:
abstract = True
allowed_methods = ['get',]
authentication = ApiKeyAuthentication()
authorization = DjangoAuthorization()
max_limit = 1000
# ──────────────────────────────────────────────────────────────────────────────
class UserResource(BaseResource):

...

# ──────────────────────────────────────
def signup(self, request, **kwargs):
...

# ──────────────────────────────────────
def signin(self, request, **kwargs):
self.method_check(request, allowed=['post'])
data = self.deserialize(
request,
request.body,
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)
try:
key = ApiKey.objects.get(user=user)
if not key.key:
key.save()
except ApiKey.DoesNotExist:
key = ApiKey.objects.create(user=user)
return self.create_response(request, {
'success': True,
'data': key.key,
})
else:
return self.create_response(request, {
'success': False,
'message': 'User is not active',
}, HttpForbidden)
else:
return self.create_response(request, {
'success': False,
'message': 'Wrong password',
}, HttpUnauthorized)

# ──────────────────────────────────────
class Meta(BaseResource.Meta):
allowed_methods = ['get', 'patch',]
queryset = User.objects.all()
resource_name = 'users'
excludes = [ 'first_name', 'last_name', 'password' ]
filtering = {
...
}
additional_urls = [
('signup/', 'signup', 'api-signup'),
('signin/', 'signin', 'api-signin'),
]
allowed_fields = ['email',]

How to create or register User using django-tastypie API programmatically?

When creating a user you need either use method set_password user.set_password(bundle.data.get('password')) or use a create_user method of User object.

user = User.objects.create_user(bundle.data.get('username'), bundle.data.get('email'), bundle.data.get('password'))

So something like this would work for you:

def obj_create(self, bundle, request=None, **kwargs):
try:
bundle = super(CreateUserResource, self).obj_create(bundle, request, **kwargs)
bundle.obj.set_password(bundle.data.get('password'))
bundle.obj.save()
except IntegrityError:
raise BadRequest('That username already exists')
return bundle


Related Topics



Leave a reply



Submit