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.
¶ 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.
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.
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.
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():
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' }
.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With