Overriding Django Admin with AllAuth - django

I don't feel that the original django admin login is secure, so I want to have /admin always redirect to my AllAuth login page, even if the user is logged in.
urls.py
admin.site.login = login_required(admin.site.login)
This will redirect users from the django admin login page if they are not logged in, but it does not redirect users if they ARE logged in. So they can still brute force it. How do I edit the login_required decorator to check for is_superuser.

You can use:
from django.contrib.auth.decorators import user_passes_test
admin.site.login = user_passes_test(lambda u: u.is_superuser)(admin.site.login)

Related

How to create custom django validation for authentication

Hi everyone) I'm new in Django. I need to do a really simple validation for sign in form. In my app can sign in only one user, with a specific username and password, for example, "my_username" and "my_password". And superuser can't sign in. I don't know do I even need a table in a database for only one user?
By now I write a simple login form with django.contrib.auth.views LoginView and this work, but for everyone who is in database and superuser.
From the django admin page create a new user.
Then if you want to allow only this user in some view just add this decorator:
from django.contrib.auth.decorators import user_passes_test
#user_passes_test(lambda user: user.username == 'allowed_username')
def my_view(request):
# your code

Django LOGIN_REDIRECT_URL does not work with "next" request parameter

Django 1.11.3
The documentation about LOGIN_REDIRECT_URL says that:
The URL where requests are redirected after login when the
contrib.auth.login view gets no next parameter.
I have LOGIN_REDIRECT_URL="some_url" in setting.py
I see "next=" (no value, just the key) in the request url when I login, so I suspect that makes Django to ignore LOGIN_REDIRECT_URL and I end up on Admin default page.
I use default login Django functionality, no custom template or anything. How do I get rid of "next=" in my request when I login (completely, no key) to see if LOGIN_REDIRECT_URL will be actually used (hopefully) ?
That’s expected behavior. Normally you want the user requesting any view requiring login (with the #login_required decorator) to be redirected to that same view after login. This is documented here
Since your view url is empty (the home url) you get next=. It’s quite uncommon to have a login required on the home page, from a user perspective it means you can’t see what you're signing up for.
If you remove the #login_required decorator for your view and just add a login button on your homepage (that goes to the regular LoginView) it will not have the next parameter and your users will be redirected to LOGIN_REDIRECT_URL as expected.
Now, if really want users to have to login on your homepage and be redirected to LOGIN_REDIRECT_URL, you have two options:
Remove the #login_required decorator and do the check and redirect in your view:
from django.conf import settings
def homepage(request):
if not request.user.is_authenticated:
return redirect(settings.LOGIN_URL)
# rest of view code
If you're using class-based views, use the LoginRequiredMixin in your view and handle handle_no_permission() yourself:
from django.contrib.auth.views import redirect_to_login
from django.contrib.auth.mixins import LoginRequiredMixin
class Home(LoginRequiredMixin, View):
def get(self):
# your view code
def handle_no_permission(self):
# pass None to redirect_field_name in order to remove the next param
return redirect_to_login(self.request.get_full_path(), self.get_login_url(), None)
If you are having LOGIN_REDIRECT_URL in your settings.py, then in case you are not giving any next parameter to url, it will go to default url mentioned in LOGIN_REDIRECT_URL.
if LOGIN_REDIRECT_URL = 'some/path/'
https://yourdomain.com/login/ will redirect to 'some/path/'
https://yourdomain.com/login/?next=/override/default/path
will redirect to 'override/default/path'

Custom login URL in django

I am a newbie in django and I was experting different options in Django. I have created a class based view which requires user authentication to view the web page. I am using the inbuilt LoginView.
When the url pattern is specified as follows
url(r'^login/', auth_views.LoginView.as_view(),name='login'),
it is correctly redirected to login page.
But when I give
url(r'^restaurant/login/', auth_views.LoginView.as_view(),name='login'),
I get a 404 when trying to access the page that requires user authentication.
But when I manually go to that url in browser, it works perfectly fine.
Why is that? Shouldn't it both cases work?
It sounds like you need to set LOGIN_URL in your settings:
LOGIN_URL = '/restaurant/login/'
or, it's better to use the URL pattern name, then you don't have to update your settings when you change the login URL
LOGIN_URL = 'login'
Not sure if I'd fully understand your question, just try to give a stupid answer.
Django 2.1.7
use namespace&url name in settings, if you have your own login view just change admin to your url namespace and name your view as 'login'
# settings.py
LOGIN_URL = 'admin:login'
then the login_required decorator will direct you the correct login page.
from django.contrib.auth.decorators import login_required
#login_required()
def month_archive(request, year, month):
production_list = Production.objects.month_archive(year, month)
context = {'production_list': production_list}
return TemplateResponse(request, 'production/production_list.html', context)
If it's a Class Based View, add decorator to urls.py
from django.contrib.auth.decorators import login_required
urlpatterns = [
path('', login_required(views.ProductionList.as_view()), name='production-list'),
path('<int:year>/<int:month>/', views.month_archive, name='production-month'),
]

How to override Django admin login next url

I'm trying to redirect to current page after login. But it always redirect to admin page. How can I override it.
view.py
#login_required(login_url='/admin')
def index(request):
template = loader.get_template('visualize/visualize_home.html')
return render(request,'visualize/visualize_home.html')
After successful login url is look like
http://127.0.0.1:8000/admin/?next=/visualize/
But I'm expecting
http://127.0.0.1:8000/visualize/

Redirecting to another page after django admin login

I am making a custom administration page in Django. I do not want to reinvent the wheel and thus want to use Django admin login form for the staff to log in and redirect them to /my-url/ afterwards.
However, I can't find the way to redirect user to a custom url after successful login at /admin/.
since I stumbled across the same problem, I noticed the url of the the default login page:
/admin/login/?next=/admin/
so I changed the login page link to
/admin/login/?next=/
to point to the main page
works for the logout page too, nice and simple
I had the same issue.
Instead of redirect after login I used the #staff_member_required decorator
for my view /my-url/ which redirects to the admin login
from django.contrib.admin.views.decorators import staff_member_required
#staff_member_required
def test_list(request):
return HttpResponse('TEST')
If class based views is used check out the method_decorator
The Django auth app comes with a login view which you can hook up to /accounts/login/ or any other url you choose. You can probably use the admin's login template admin/login.html if you don't want to write your own.
By using the login view, the LOGIN_REDIRECT_URL parameter will work. The purpose of the /admin/ page is to display the admin index. I would avoid trying to use it as the login page.
Set LOGIN_REDIRECT_URL in your settings.py file. Documented here.
If you have ?next= parameter set is not enough to set LOGIN_REDIRECT_URL in you setting.py. You need to also handel this parameter. As say docs (https://docs.djangoproject.com/en/4.1/ref/settings/#login-redirect-url):
LOGIN_REDIRECT_URL
Default: '/accounts/profile/'
The URL or named URL pattern where requests are redirected after login
when the LoginView doesn’t get a next GET parameter.
In my case I just set REDIRECT_FIELD_NAME = "" instead of REDIRECT_FIELD_NAME = "next" in my django.contrib.auth and it works fine.