Custom url for django admin - python

For an extra little bit of security I want to change the default django admin url to the custom one, e.g. change mysite.com/admin/ to mysite.com/mysecretadmin/ so that admin is completely unaccessible via default url.
I tried some solutions from the internet, for example I changed urls.py like this:
from django.conf.urls import patterns, url, include
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('api.views',
...,
...,
url(r'^secret-admin-url/', include(admin.site.urls)),
)
Nothing worked for me, sadly. Does anyone know the solution? I use django 1.5.4.

Refer to the section 'Hooking AdminSite instances into your URLconf' in the url
below
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#hooking-adminsite-to-urlconf

For those who find this question in recent times. Based on the Django 3.1 docs:
register the default AdminSite instance django.contrib.admin.site at the URL /admin/:
# main project urls.py
from django.contrib import admin
from django.urls import path
urlpatterns = [
path("admin/", admin.site.urls),
]
you can simply change the admin/ url to anything you wish:
urlpatterns = [
path("my_custom_url/", admin.site.urls),
]

If you do not want to use the default page /admin you can add a secret key to admin. So in urls.py
urlpatterns = [
path('admin_eTiOmEthelInEwathbace/', admin.site.urls,),
]
If in your template you have a link
Admin
then this will reference to the above site with url: http://127.0.0.1:8000/admin_eTiOmEthelInEwathbace/
Now you do not want to publish this secret_key, therefore get it from an environment variable with for example decouple, so urls.py then becomes
from decouple import config
SECRET_ADMIN = config('SECRET_ADMIN')
urlpatterns = [
path(f'admin_{SECRET_ADMIN}/', admin.site.urls,),
]

If you want to prevent brute force or dictionary attack and your admin login page not accessible for unauthorized user,normal user. please follow this step:
First install django admin honeypot and signal
pip install django-admin-honeypot(inastall in settings.py)
pip install django-honeypot-signals(inastall in settings.py)
override this .txt file(because future tag is deprecated):
templates/honeypot_signals/notification.txt:
{% load i18n %}
{% blocktrans with site_name=site.name %}
{% endblocktrans %}
Invalid login attempt from your duplicate ADMIN panel..
• Review entry at http://{{ site.domain }}{% url "admin:admin_honeypot_loginattempt_change" object.id %}
Username: {{ object.username }}
IP: {{ object.ip_address }}
Timestamp: {{ object.timestamp }}
django-admin-honeypot make a fake admin login page and django honeypot signal send email to admin with credentials if any person try to access your fake admin login page.
How to access main admin login page?:
pip install django-decorator-include
Your main urls.py:
from django.contrib import admin
from django.urls import path
from django.urls.conf import include
from . import settings
from decorator_include import decorator_include
from django.contrib.auth.decorators import login_required, user_passes_test
from django.core.exceptions import PermissionDenied
from django.core.mail.message import EmailMessage
from datetime import datetime
from django.views.generic.base import RedirectView
def only_user():
def check(user):
if user.is_authenticated and user.is_superuser or user.is_staff:
return True
time = datetime.now()
message = f'----------------------------------\nName: {user.username}\nEmail: {user.email}\nTime: {time}.\n----------------------------------\n • {user.username} is not a staff user or admin.For some security reasons..Please block this user from your admin panel(Blacklist).'
email = EmailMessage(
f'📛📛📛Alert!! {user.username} is try to accessing your admin panel!!',
message,
settings.EMAIL_HOST_USER,
[settings.EMAIL_HOST_USER],
)
email.fail_silently = False
email.send()
raise PermissionDenied
return user_passes_test(check)
urlpatterns = [
path('', include('product.urls')),
#This is all fake admin urls...
path('admin/', include('admin_honeypot.urls',
namespace='admin_honeypot')),
path('site/admin/',RedirectView.as_view(url='/admin')),
path('user/admin/',RedirectView.as_view(url='/admin')),
path('secure/admin/',RedirectView.as_view(url='/admin')),
path('mysite/admin/',RedirectView.as_view(url='/admin')),
path('admin/secure',RedirectView.as_view(url='/admin')),
path('real/admin/',RedirectView.as_view(url='/admin')),
#This is real admin login page url
path('custom_url/',
decorator_include([login_required, only_user()],
admin.site.urls)),
]
For this way you can not access directly your admin login page.. first you need to login your website and then accessible your admin panel..
How to protect website's login page from the attackers?:
- Use django defender (https://django-defender.readthedocs.io/en/latest/)
---------------------OR-------------------------
- Use google hidden(ReCaptchaV2Invisible) recaptcha field
(https://pypi.org/project/django-recaptcha/)
If any unauthorized users terrible activity detected.You block their IP address or username by using this django package:
pip install django-blacklist
Read docs : django-blacklist
•sorry for my English

Related

How to logout from Django with custom user model and custom logout view?

I made an app and extended AbstractUser to add some fields to my User model. After that, everything works as expected (login, create user, reset password...) but when I try to logout using the default
django.contrib.auth.LogoutView or include('django.contrib.auth.urls')
it will simply ignore the logout. When I go back to the restricted page I can enter and see the content and my user is actually logged in!
I created a custom logout view like this
def custom_logout(request):
print('Loggin out {}'.format(request.user))
auth.logout(request)
print(request.user)
return HttpResponseRedirect('/restrictedpage')
on the restrictedpage I have a print statement to show the user
print("User logged: {}".format(request.user))
When I click logout this is what shows up in the console:
"GET /restrictedpage HTTP/1.1" 200 19820
User logged: ceterre
----- This is where i click logout ------
Loggin out AnonymousUser
AnonymousUser
"GET /accounts/logout/ HTTP/1.1" 302 0 ----- this redirects me to /restrictedpage
User logged: ceterre
"GET /restrictedpage HTTP/1.1" 200 19820
this literally translate to:
- I know ceterre is logged
- logging out ceterre
- user logged: AnonymousUser
- redirect to restricted page (where I should have no access since im supposedly logged out)
- user logged: ceterre (without any login or anything...)
Login and logout is part of Django (and AbstractUser too) so you don't need extend this parts of code. One thing you must do is add in settings.py file this two line of code:
LOGIN_REDIRECT_URL = 'template_name'
LOGOUT_REDIRECT_URL = 'template_name'
from django.contrib.auth import logout
def custom_logout(request):
print('Loggin out {}'.format(request.user))
logout(request)
print(request.user)
return HttpResponseRedirect('/restrictedpage')
This worked for me and should work for you also.
Here is a solution that works for Django 3+.
Replace django.contrib.admin with my_admin module.
INSTALLED_APPS = [
...
'my_admin.apps.AdminConfig',
# 'django.contrib.admin',
...
]
AdminConfig (my_admin/apps.py):
from django.contrib.admin.apps import AdminConfig as ContribAdminConfig
class AdminConfig(ContribAdminConfig):
default_site = 'my_admin.admin_site.AdminSite'
AdminSite (my_admin/admin_site.py):
from django.contrib.admin import AdminSite as ContribAdminSite
from django.views.decorators.cache import never_cache
class AdminSite(ContribAdminSite):
#never_cache
def logout(self, request, extra_context=None):
"""
Define your custom logout functionality here.
Checkout the super logout method to get a baseline implementation.
Log out the user for the given HttpRequest.
This should *not* assume the user is already logged in.
"""
# Your logout code here.
return super().logout(request, extra_context)
Django 3+: Using a custom class-based view
Template view
To avoid conflicts with django.contrib.auth and its defaults, create a new view with a unique name. Use the built-in function django.contrib.auth.logout to actually sign out the user.
from django.contrib.auth import logout
from django.http import HttpRequest
from django.shortcuts import render
from django.views.generic.base import TemplateView
class SignedOutView(TemplateView):
template_name = "registration/signed_out.html"
def get(self, request: HttpRequest):
logout(request)
return render(request, self.template_name)
Template
Add a new signed_out.html template under the registration folder.
{% extends "base.html" %}
{% block content %}
<section id="page" class="">
<p>You are signed out!</p>
<p>Click here to sign in again.</p>
</section>
{% endblock content %}
URLs
Update your URL paths.
from django.conf.urls import include
from django.contrib import admin
from django.urls import path
from .views import SignedOutView
urlpatterns = [
path("accounts/", include('django.contrib.auth.urls')),
path("admin/", admin.site.urls),
path("signed-out/", SignedOutView.as_view(), name="sign-out"),
]
Use the new sign-out view
Sign out

Is a position of adding #csrf_exempt wrong?

I wanna connect my Swift app & Python Django Server in sending Image(I wanna send images from Swift app to Server) When I tried to do it,I got an error in Xcode
<div id="info">
<h2>Help</h2>
<p>Reason given for failure:</p>
<pre>
CSRF cookie not set.
</pre>
<p>In general, this can occur when there is a genuine Cross Site Request Forgery, or when
<a
href="https://docs.djangoproject.com/en/1.10/ref/csrf/">Django's
CSRF mechanism</a> has not been used correctly. For POST forms, you need to
ensure:</p>
<ul>
<li>Your browser is accepting cookies.</li>
<li>The view function passes a <code>request</code> to the template's <code>render</code>
method.</li>
<li>In the template, there is a <code>{% csrf_token
%}</code> template tag inside each POST form that
targets an internal URL.</li>
<li>If you are not using <code>CsrfViewMiddleware</code>, then you must use
<code>csrf_protect</code> on any views that use the <code>csrf_token</code>
template tag, as well as those that accept the POST data.</li>
<li>The form has a valid CSRF token. After logging in in another browser
tab or hitting the back button after a login, you may need to reload the
page with the form, because the token is rotated after a login.</li>
</ul>
<p>You're seeing the help section of this page because you have <code>DEBUG =
True</code> in your Django settings file. Change that to <code>False</code>,
and only the initial error message will be displayed. </p>
<p>You can customize this page using the CSRF_FAILURE_VIEW setting.</p>
</div>
</body>
</html>
So,I think adding csrf decorators to Django Server is needed. I added it to my codes like
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.views.decorators.http import require_POST
from .forms import RegisterForm
from django.contrib.auth import authenticate, login
from .models import Post
from .forms import UserImageForm
from .models import ImageAndUser
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def upload_save(request):
photo_id = request.POST.get("p_id", "")
if (photo_id):
photo_obj = Post.objects.get(id=photo_id)
else:
photo_obj = Post()
files = request.FILES.getlist("files[]")
photo_obj.image = files[0]
# photo_obj.image2 = files[1]
# photo_obj.image3 = files[2]
photo_obj.save()
# return render(request, "registration/accounts/photo.html")
photos = Post.objects.all()
context = {
'photos': photos,
}
return render(request, 'registration/accounts/photo.html', context)
But when I did same thing in Swift app,totally same error happened.
I think the position of adding #csrf_exempt is wrong,but I do not know how to fix this.And maybe the position of #csrf_exempt is ok,another point is wrong,I do not know.
My sending url is written in Swift is http://localhost:8000/admin/accounts/post/42/change/ .
In Django side,MyAPP's urls.py is
from django.conf import settings
from django.conf.urls import include, url
from django.conf.urls.static import static
from django.contrib import admin
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^accounts/', include('accounts.urls')),
url(r'^api/', include('UserToken.urls')),
url(r'^accounts/', include('accounts.urls', namespace='accounts')),
url(r'^ResultJSON/', include('ResultJSON.urls')),
url(r'^api/1.0/', include('accounts.api_urls', namespace='api')),
url(r'^api/1.0/login/', include('accounts.apitoken_urls', namespace='apilogin')),
] +static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
accounts's urls.py is
from django.conf.urls import url
from . import views
from django.contrib.auth.views import login, logout
from django.views.generic import TemplateView
urlpatterns = [
url(r'^login/$', login,
{'template_name': 'registration/accounts/login.html'},
name='login'),
url(r'^logout/$', logout, name='logout'),
url(r'^regist/$', views.regist,name='regist' ),
url(r'^regist_save/$', views.regist_save, name='regist_save'),
url(r'^profile/$', views.profile, name='profile'),
url(r'^photo/$', views.photo, name='photo'),
url(r'^upload/(?P<p_id>\d+)/$', views.upload, name='upload'),
url(r'^upload_save/$', views.upload_save, name='upload_save'),
url(r'^kenshinresults$', TemplateView.as_view(template_name='registration/accounts/kenshin_result.html'),
name='kenshinresults'),
url(r'^tcresults$', views.tc,name='tcresults'),
]
Please tell me what is wrong.
/admin/accounts/post/42/change/ is a URL in the Django admin. Your upload_save view which uses the csrf_exempt decorator is hooked up to /accounts/upload_save/ in your URL config.

path is deprecated (django.contrib.auth.views.password_reset_confirm)

I am working on password reset on django project, when the email address is sent i get
path is deprecated (django.contrib.auth.views.password_reset_confirm)
at the command prompt.
Here is my url.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from doreenselly import views
from django.conf import settings
from django.conf.urls.static import static
from django.contrib.auth.views import password_reset, password_reset_done, password_reset_confirm, password_reset_complete
from django.views.generic import TemplateView
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', 'selly.views.index', name="index"),
url(r'^selly/', include('selly.urls')),
url(r'^delete_item/(?P<item_id>[-\w]+)/$', views.delete_item, name='delete_item'),
url(r'^admin_delete_item/(?P<item_id>[-\w]+)/$', views.admin_delete_item, name='admin_delete_item'),
# Password reset urls
url(r'^reset/form/$', TemplateView.as_view(template_name = 'registration/password_reset_email.html')),
url(r'^resetpassword/passwordsent/$', password_reset_done, name="password_reset_done"),
url(r'^reset/password/$', password_reset, name="password_reset"),
url(r'^reset/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$', password_reset_confirm, name="password_reset_confirm"),
url(r'^reset/done/$', password_reset_complete, name="password_reset_complete"),
]
Your urls look OK, so my guess is the problem is in your template.
Look for
{% url 'django.contrib.auth.views.password_reset_confirm' uidb64=uid token=token %}
in your registration/password_reset_email.html template, and replace it with
{% url 'password_reset_confirm' uidb64=uid token=token %}
If that doesn't solve the problem, then you need to find out where the warning is coming from. You can run the dev server with the -W flag to turn warnings into exceptions.
python -W error manage.py runserver
When you send the password reset email, you will get a traceback which will show you where the problem is.

Login page displayed even if the user is already logged in

I use Django's authentication view django.contrib.auth.views.login to log in my users.
urls.py
urlpatterns = patterns('',
url(r'^accounts/login/$', 'django.contrib.auth.views.login'),
)
Here is the doc regarding this functionality.
My problem: The login page is displayed even if the user is already connected.
For django 2.x, you can simply do this
from django.contrib.auth import views as auth_views
from django.urls import path
urlpatterns = [
path('login/', auth_views.LoginView.as_view(redirect_authenticated_user=True), name='login'),
]
You can just use the contrib login view with your own modifications in your own view. Just change the login url to point to your own view, then check if they are already logged in:
views.py
from django.contrib.auth.views import login as contrib_login
def login(request):
if request.user.is_authenticated():
return redirect(settings.LOGIN_REDIRECT_URL)
return contrib_login(request)

DJANGO: How to allow Users to change password?

So I have Users (from django.contrib.auth.models import User) and UserProfiles. in my UserProfile view there is an edit link. This edit link allows a User to change their User settings. In the password section of the form I see help text that says:
"Use '[algo]$[salt]$[hexdigest]' or use the change password form."
The "change password form" is actually a link to http://127.0.0.1:8000/user/1/user_edit/password/, when I click the link I get an error message saying:
ViewDoesNotExist at /user/1/user_edit/password/
Could not import testdb.views.django.contrib.auth.views. Error was: No module named django.contrib.auth.views
I've been following the documentation: https://docs.djangoproject.com/en/dev/topics/auth/
What am I doing wrong? I hear that this should use djangos templates, do I need to copy those over to my apps template folder? if so, where are they?
URLS.PY
from django.conf.urls.defaults import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('testdb.views',
url(r'^$', 'index'),
url(r'^^user/(?P<user_id>\d+)/$', 'user_detail'),
url(r'^user/(?P<user_id>\d+)/user_edit/$', 'user_edit'),
url(r'^user/(?P<user_id>\d+)/user_edit/password/$', 'django.contrib.auth.views.password_change', {'template_name': 'password_change_form'}),
)
You have a wrong URL pattern defined: Django tries to find testdb.views.django.contrib.auth.views as you define the password_change view inside patterns('testdb.views',.
Add a second pattern:
urlpatterns += patterns('django.contrib.auth.views',
url(r'^user/(?P<user_id>\d+)/user_edit/password/$', 'password_change')
)
That should resolve your issue.
cfedermann has a solution to your issue, but I'm confused as to why you've defined the password_change URL in the first place. This functionality is built-in to the admin, and - like all the other admin pages - the URL is defined already by the admin code itself.

Categories