I have successfully setup an authentication system with django application using the popular django-allauth package. I suspended a registered user by updating SuspendedUser.is_active=False but whenever I try to login as the suspended user I'd get the failed authentication message The username and/or password you specified are not correct..
Do I need any special configuration to display the account_inactive.html template as I cannot find anything that mentions that in the official documentation?.
Note: django-allauth version is 0.49.0 and django version is 4.0.3
You can override log-in function of django-allauth. And you can create a dield under your user model names is_suspended instead of giving is_active=False. And in login function before login() put an if statement.
#in django-allauth login function
if request.user.is_suspended:
message(request,'You have suspended! Cannot login!')
return
render(request, 'user/user_policy.html' {'message':message})
or search django-alluth signals
#in User model:
class User(models.Model):
...
...
...
is_suspended = models.BooleanField(default=False)
After reviewing my configurations, I realized I was using a custom authentication backend in my settings.py file. django-allauth requires allauth.account.auth_backends.AuthenticationBackend to handle authentication and permissions.
Adding this to my project config solved the problem
AUTHENTICATION_BACKENDS = [
# Needed to login by username in Django admin, regardless of `allauth`
'django.contrib.auth.backends.ModelBackend',
# `allauth` specific authentication methods, such as login by e-mail
'allauth.account.auth_backends.AuthenticationBackend',
]
Although it was stated in the docs
Related
I made registration via social networks using the allauth library.
Added the necessary settings:
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = "email".
and applications:
"allauth", #registration
"allauth.account", # registration
"allauth.socialaccount", # registration
"allauth.socialaccount.providers.vk", # registration via VK.
and in urls.py I also wrote:
url(r"^accounts/", include("allauth.urls"))
The problem is that sometimes the provider after registration may not provide an email.
And my users are identified using mail.
Signup:
I want the user to be redirected to a page with an email entry and send a confirmation link to this email after the suppliers confirm the entered data is correct.
Signin:
I want to return the JWT token to the user after confirming the providers that the entered data is correct
How to implement a signin/signup system in Django DRF JWT with allauth library?
(apparently I need to write custom views, but I tried - unsuccessfully)
I'm trying to customize allauth's default SignUpView and SignUpForm to allow me to create other users while already logged in. The default behavior prevents me from doing this: in other words, I can only sign up for a new account if I'm not authenticated.
How do I override this behavior?
I presume I'll have to override the SignupView in views.py but I'm not sure what to look for... I played around with RedirectAuthenticatedUserMixin, but to no avail.
Forms.py
from allauth.account.forms import SignupForm
class SubUserForm(SignupForm):
USER_TYPES = [
(2,'customer'),
(3,'vendor'),
(4,'supplier')
]
first_name = forms.CharField(max_length=45)
last_name = forms.CharField(max_length=45)
user_type = forms.CharField(widget=forms.Select(choices=USER_TYPES))
Views.py
from allauth.account.views import SignupView
class SubUserSignupView(SignupView):
template_name = 'accounts/new_user_signup_form.html'
form_class = SubUserForm
view_name = 'sub_user_signup'
sub_user_signup = SubUserSignupView.as_view()
urls.py
urlpatterns = [
path('sub_user/',views.sub_user_signup,name='sub_user_signup'),
]
To put in context
My app allows for a 'parent' user to sign up multiple 'children' users (called 'subuser' in the code above) using allauth. In my case, an organization can create several customers, merchants, suppliers, etc. When a parent user creates a child user, a verification email is sent to the child user, who then activates his account and is prompted to enter a password. I use 2 signup forms; the default allauth signup (for parent accounts), and a customized signup form (for children accounts), which also extends from allauth.
Although the registration flow above works well, a parent user can only sign up new children users (trigger email verification) when logged out. I'm struggling to identify what I need to prevent this from happening.
Navigate to the allauth directory, under app settings, set this to False
ACCOUNT_AUTHENTICATED_LOGIN_REDIRECTS (=True)
The default behaviour is to redirect authenticated users to LOGIN_REDIRECT_URL when they try accessing login/signup pages.
By changing this setting to False, logged in users will not be redirected when they access login/signup pages.
This also worked
Navigate to the allauth folder, under views find SignupView.
Deleting the redirectAuthenticatedUsermixin works
New issue is that you are logged in as the new user, fixing that currently.
First of all, this article maybe useful:
https://tech.serhatteker.com/post/2020-06/custom-signup-view-in-django-allauth/
The reason you can only sign up for a new account if you're not authenticated is because of this Allauth's mixin: RedirectAuthenticatedUserMixin (as suggested by Anthony M).
So, you have to override this mixin and the allauth's signup view with your own code.
It is very important that you register the url before allauth urls.
Hope it helps.
I have an app with multi user type, Author, Moderator and Manager. this groups have different android apps. and I've used django simple JWT token for login. the problem is that Author can login in moderator app and moderator can login in others app and so on.
the question is that,
how can i separate login urls and conditions for these groups??
I have used django user model for authentication, and used django groups for defining three groups. just admin can create users and when he create a user, define user's group. in simple jwt we use this pattern for authentication
urlpatterns = [
...
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
...
]
and my authentication backend setting is this:
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'account.authentication.MobileAuthBackend',
)
all user can login to my apps. not important their groups. because system just check django user model.
now i want to have separate login url for this three android apps and have specific login condition for every groups. but i don't know how should i do that!?
Do you try it from admin page? You can give different permissions for different users.
We are using django-rest-framework with django-rest-framework-jwt for authentication and it works everywhere except the django admin page at ip:port/admin/. That still wants username and password.
Is there a setting or way to bypass that so it recognizes the JWT?
Is the /admin/ page always required to use name/password? I think the built in token auth works with it.
jwt is the only auth set in the settings.py file. Session authentication is not in there anymore.
The issue is that Django isn't aware of djangorestframework-jwt, but only djangorestframework, itself. The solution that worked for me was to create a simple middleware that leveraged the auth of djangorestframework-jwt
In settings.py:
MIDDLEWARE = [
# others
'myapp.middleware.jwt_auth_middleware',
]
Then in my myapp/middleware.py
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from django.contrib.auth.models import AnonymousUser
from rest_framework import exceptions
def jwt_auth_middleware(get_response):
"""Sets the user object from a JWT header"""
def middleware(request):
try:
authenticated = JSONWebTokenAuthentication().authenticate(request)
if authenticated:
request.user = authenticated[0]
else:
request.user = AnonymousUser
except exceptions.AuthenticationFailed as err:
print(err)
request.user = AnonymousUser
response = get_response(request)
return response
return middleware
Important Note:
This is a naive approach that you shouldn't run in production so I only enable this middleware if DEBUG. If running in production, you should probably cache and lazily evaluate the user as done by the builtin django.contrib.auth module.
The problem can be not in the authentication method you use. If you customize User model, it can happen that create_superuser method doesn't update is_active flag in user instance details to True. This case django authentication backend (if you use ModelBackend) can recognize that user is not active and do not allow to authenticate. Simple check - just see what value has is_active field of the superuser you create. If it False, update it manually to True, and try to login. If it is the reason of your problem you need to override create_superuser and create_user method of UserManager class.
I was wondering if there's an easy way to configure the Django Admin UI (eg at http://mysite.com/admin) so that I don't need to authenticate/login?
I've tried tweaking urls.py but couldn't get it to bypass the login screen:
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
)
I'd like to go to http://mysite.com/admin and see the list of django objects without having to login.
Thanks.
Django admin framework uses 'is_staff' flag on the 'User' object to verify the permission to use admin site.
So it needs an user to be authenticated to verify his admin related permissions.
If you want to disable this, you have to override the 'index' method of the admin site.
It is available at django.contrib.admin.sites.
def index(self, request, extra_context=None):
"""
Displays the main admin index page, which lists all of the installed
apps that have been registered in this site.
"""