I would like to add captcha on my django login form using Django Simple Captcha found here: http://code.google.com/p/django-simple-captcha/
This works great if you create a new form but I'm using the django.contrib.auth.forms the one that comes with django. Any idea how I might be able to implement captcha with the existing django auth views or any ways? Thank you!
Please do not suggest using Google reCaptcha.
My urls.py
from django.contrib.auth import views as auth_views
urlpatterns = [
path('login/', auth_views.LoginView.as_view(template_name='login.html'), name='login')
,...
]
My login.html
<form class="fadeIn second" method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary"> Login </button>
</form>
My Forms.py
from captcha.fields import CaptchaField
class MyFormCaptcha(forms.Form):
captcha = CaptchaField()
This video and this GitHub project solved my problem. You can customize the project code according to your needs. For me it is as follows.
My urls.py
urlpatterns = [
...
path('captcha/',include('captcha.urls')),
path('submit',submit,name='submit')
]
My forms.py
from captcha.fields import CaptchaField
class MyForm(forms.Form):
captcha=CaptchaField()
My login.html
<form action="/submit" method="post">
{% csrf_token %}
<div>
<label for="fullname">Full Name</label>
<input type="text" id="fullname" name="fullname">
</div>
<br>
<div>
<label for="email">Email</label>
<input type="text" id="email" name="email">
</div> <br>
{{form.captcha}}
<button type="submit">Submit</button>
</form>
My views.py How to log a user in?
from django.contrib.auth import authenticate, login
def test(request):
form=MyForm()
return render(request,'captcha/home.html',{'form':form})
def submit(request):
if request.method == 'POST':
form=MyForm(request.POST)
if form.is_valid():
name=request.POST['fullname']
email=request.POST['email']
print('success')
print(name)
print(email)
user = authenticate(request,username=username,password=password)
if user is not None:
login(request, user)
return redirect('/homepage') # Redirect to a success page.
else:
# Return an 'invalid login' error message.
print('fail')
messages.success( request,f 'login failed! username or passwoed is wrong!'
return redirect('login')
Related
I'm trying to set up passkeys to a testing Django website I made a while back following this guide, but at some point I get asked to "In your login view, change the authenticate call to include the request as follows":
user=authenticate(request, username=request.POST["username"],password=request.POST["password"])
However I don't have a Login view as I'm using this in my urls.py:
path("login/", userViews.LoginView.as_view(), name="login"),
I've tried to look up for guides in how to set up a login view manually but they all get me to the simplified version I'm using already.
Is there way to add that line regardless?
Otherwise, how do I create a login view manually and how should I change my login.html file?
Thanks!
Usually, we create a form in forms.py with a username and password then render this form into html template and within our view we can authenticate and then login our user.
HTML template
<body>
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
<form action="" method="post">
{% csrf_token %}
<label for="">username</label>
<input type="text" name="username" id="">
<label for="">Password</label>
<input type="password" name="password" id="">
<input type="submit" value="Login">
</form>
</body>
then handle this form in views.py file by creating loginview for it
def loginview(request):
if request.method == 'POST':
user = authenticate(request, username=request.POST["username"],
password=request.POST["password"])
if user:
login(request, user)
messages.success(request, 'Logged in successfully')
return redirect('home')
else:
messages.error(request, 'Logged in Fail')
return render(request, 'test_app/home.html')
url path
from .views import loginview
urlpatterns = [
path('', loginview, name='login'),
]
I am new to Django Authentication system and I am unable to find the correct debugging method.
I want to create a function to handle login requests and I have done the necessary steps to do the same.
created a login url path in main project URLS.py file.
path('members/', include('django.contrib.auth.urls')),
path('members/', include('members.urls')),
created a login url in members app to point to a function created in views.py
urlpatterns = [
path('login/', views.login_user, name='login'),]
defined what to do when user comes to specific url
def login_user(request):
if request.method == 'POST':
print('-'*100)
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
messages.success(request, ("You are now logged in"))
return redirect('index')
else:
messages.success(request, ("Invalid credentials"))
return redirect('login')
return render(request, 'registration/Login.html')
I have created a Login Page in templates folder.
{% extends 'Base.html'%}
{% block title %}
Login to the Blog Page
{% endblock %}
{% block content%}
<h1>Members Login</h1>
<div class="form-group">
<form method="POST" action="">
{% csrf_token %}
<div class="mb-3">
<label for="exampleInputEmail1" class="form-label">User Name</label>
<input type="text" class="form-control" name = "username">
<div id="emailHelp" class="form-text">We'll never share your email with
anyone else.</div>
</div>
<div class="mb-3">
<label for="exampleInputPassword1" class="form-label">Password</label>
<input type="password" class="form-control" name="password">
</div>
<button type="submit" class="btn btn-primary">Login</button>
</form>
<br>
</div>
{% endblock %}
Now when I get to the /members/login after submitting the user details the print statement in post method is not printed in the console. So I am suspecting that the post request is not being redirected to the login_user function. Can anyone help me out to identify why?
Djnago will fire the view that it first finds for the path members/login, and that is the login view of the django.contrib.auth module. You can swap the order of the views to visit the login view of your view:
urlpatterns = [
path('members/', include('members.urls')), # 🖘 `members.urls first
path('members/', include('django.contrib.auth.urls'))
]
But it might be better to give your view a different path, to prevent any confusion.
I am trying to authenticate a registered user . redirect is not working in my case. after clicking the login button it keep on showing the login page again. i want the user to go to home page upon the successful login. Here are my files.
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponseRedirect
from django.contrib import messages
from django.contrib.auth import authenticate, login, logout
def register_new_a(request):
saved = False
if request.method == "POST":
# take whatever is posted to the Details Form
form = DetailsForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Your account details have been saved!')
return HttpResponseRedirect('/register_new_a?saved=True')
else:
form = DetailsForm()
if 'saved' in request.GET: # sends saved var in GET request
saved = True
return render(request, 'register1.html', {'form': form, 'saved': saved})
def loginUser(request):
if request.method == "POST":
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
# at backend authenticated the credentials
login(request, user)
return redirect('home') # not working
return render(request, 'login_a.html')
urls.py
from django.contrib import admin
from django.urls import path
from home import views
urlpatterns = [
path("", views.index, name='home'),
path("login", views.loginUser, name='login'),
path("logout", views.logoutUser, name='logout'),
#path("register", views.register, name='register'),
path("register_new_a", views.register_new_a, name='register_new_a'),
path("register_new_b", views.register_new_b, name='register_new_b'),
path("about", views.about, name='about'),
]
login_a.html
{% extends 'base.html'%}
{% block title %}Login{% endblock title %}
{% block body %}
<div class="container my-3" >
<h1 class="display-3" align="center">Login Here</h1>
<br>
<h1 class="display-6" >STEP 1: </h1>
<form method="post" action="">
{% csrf_token %}
<div class="mb-3">
<label for="Username1" class="form-label" >Username </label>
<input type="username"class="form-control" name="username"></input>
</div>
<div class="mb-3">
<label for="Password1" class="form-label">Password</label>
<input type="password" class="form-control" id="Password1" name="password">
</div>
New user? Register Here
<button type="submit" class="btn btn-primary float-end" style="background: #0a9396" > Next</button>
</form>
</div>
{% endblock body %}
Any help would be appreciated.
how i can set my own password at any login template in my django website without using django default login authentication.
A sample of my website is given in screen shot of my project.I want to set a own password in that page.sample of my project
so i guess you want to create a login using your own password from within the website without using Django shell.
In-order to achieve the above you can use a registration page (html) to accept the username/user id and the password.
form HTML code
<form action="{% url 'reg_method' %}" method="POST">
{% csrf_token %}
<div class="form-group"><label for="name">Name</label><input class="form-control item" type="text" id="name" name="name"></div>
<div class="form-group"><label for="password">Password</label><input class="form-control item" type="password" id="password" name="password"></div>
<div class="form-group"><label for="email">Email</label><input class="form-control item" type="email" id="email" name="email"></div><button class="btn btn-primary btn-block" type="submit">Sign Up</button>
</form>
In urls.py
from django.urls import path
from . import views
urlpatterns = [
path('',views.index ,name='index'),
path('auth_reg',views.reg_method ,name='reg_method'),
]
In your app's views.py define a method for processing the request from registration page.
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.contrib.auth.models import User
def reg_method(request):
if request.method == 'POST':
if request.POST.get('name') and request.POST.get('password') and request.POST.get('email'):
name = request.POST.get('name')
password = request.POST.get('password')
email = request.POST.get('email')
User.objects.create_user(username=name, email=email, password=password, )
return HttpResponse('User successfully created')
else:
return HttpResponse('User details are not entered')
Now you can use your login page to login the site using the username/id and password that you have used to register.
PS: additionally you can use the Authentication method to check whether the user exists or not. by importing.,
from django.contrib.auth import authenticate
I am using a custom user model for my Django project and I can log in via /admin/ perfectly fine. But when I go to /accounts/login and try to log in, it just bounces me back to the login page without logging in. I am using django-registration-redux with the simple backend.
Via logging I discovered that the error happens in this method in django.contrib.auth.__init__.py:
def get_user(request):
"""
Returns the user model instance associated with the given request session.
If no user is retrieved an instance of `AnonymousUser` is returned.
"""
from .models import AnonymousUser
user = None
try:
#
# EXCEPTION THROWN ON BELOW LINE
#
user_id = _get_user_session_key(request)
backend_path = request.session[BACKEND_SESSION_KEY]
except KeyError:
pass
else:
if backend_path in settings.AUTHENTICATION_BACKENDS:
backend = load_backend(backend_path)
user = backend.get_user(user_id)
# Verify the session
if hasattr(user, 'get_session_auth_hash'):
session_hash = request.session.get(HASH_SESSION_KEY)
session_hash_verified = session_hash and constant_time_compare(
session_hash,
user.get_session_auth_hash()
)
if not session_hash_verified:
request.session.flush()
user = None
return user or AnonymousUser()
Any ideas? /accounts/register/ performs as expected, although I have overridden RegistrationView. Perhaps I have to do the same thing for logging in?
Login.html
{% extends "base.html" %}
{% load staticfiles %}
{% block body_block %}
<link href="{% static 'css/signin.css' %}" rel="stylesheet">
<div class="container">
<div class="jumbotron">
<h1 class="display-3" align="center">Login</h1>
</div>
<form method="post" action=".">
{% csrf_token %}
<h2 class="form-signin-heading">Please sign in</h2>
<label for="inputEmail" class="sr-only">Username</label>
<input type="text" name="email" id="id+username" class="form-control" placeholder="Username" required autofocus>
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" name="password" id="id_password" class="form-control" placeholder="Password" required>
<button class="btn btn-lg btn-primary btn-block" type="submit" value="Submit">Login</button>
</form>
Not a member?
Register
</div>
<p>
</p>
{% endblock %}
Urls.py
class MyRegistrationView(RegistrationView):
success_url = '/'
form_class = UserProfileRegistrationForm
def get(self, request, *args, **kwargs):
form = self.form_class(initial=self.initial)
return render(request, self.template_name, {'form': form})
def register(self, form):
logging.debug("THIS IS MY REGISTER")
new_user = form.save(commit=False)
new_user.set_password(form.cleaned_data['password1'])
new_user.save()
login(self.request, new_user)
logging.debug("Logged in")
signals.user_registered.send(sender=self.__class__,
user=new_user,
request=self.request)
logging.debug("After signals")
return new_user
urlpatterns = [
url(r'^', include('base.urls')),
url(r'^admin/', admin.site.urls),
url(r'^accounts/register/$', MyRegistrationView.as_view(), name="registration_register"),
url(r'^accounts/password/change/$', MyRegistrationView.as_view(), name="auth_password_change"),
url(r'^accounts/password/change/done/$', MyRegistrationView.as_view(), name="auth_password_changed"),
url(r'^accounts/', include('registration.backends.simple.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
EDIT:
I have a temporary fix of throwing a view into login in urls.py. Something tells me this is extremely dirty but it seems to work... for now. I'm open to better alternatives.
url(r'^accounts/login/$', my_view, name="login"),
def my_view(request):
if request.POST:
username = request.POST['email']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return render(request, 'index.html', {})
# Redirect to a success page.
else:
# Return an 'invalid login' error message.
pass
else:
return render(request, 'registration/login.html', {})
Try using {{ form }} in your login template, instead of rendering the fields manually. This can show whether the problem is in your template or elsewhere.
In this case, I think that the form fields should be username and password, not email and password as you have.
<input type="text" name="username" id="id_username" class="form-control" placeholder="Username" required autofocus>
<input type="password" name="password" id="id_password" class="form-control" placeholder="Password" required>