I'm using class based views to render a template. In that same class, I also have a post request to allow for the submission of a form.
However, when I submit the form, I get the CSRF cookie not set error. I did use the {% csrf_token %} but still doesn't work.
Here is my code:
class SignIn(View):
def get(self, request):
# email = request.POST['email']
# password = request.POST['password']
template = loader.get_template('signin.html')
logging.info(request)
return HttpResponse(template.render())
def post(self, request):
email = request.POST['email']
password1 = request.POST['password1']
password2 = request.POST['password2']
template = loader.get_template('signin.html')
logging.info(request.__dict__)
logging.info(password1)
logging.info(email)
if User.objects.filter(email=email).exists():
messages.info(request, 'E-mail Exists!')
return redirect('signup')
elif password1 != password2:
messages.info(request, 'PASSWORD DOESNT MATCH')
return redirect('signup')
new_user = User.objects.create_user(email, email, password1)
return HttpResponse(template.render())
This is my template:
<html>
<div>
<p>
Signup
</p>
<form method = "POST" action="/signup">
{% csrf_token %}
username:
<br/>
<input type="text" name="email" />
<br/>
Password:
<br/>
<input type="password" name="password1" />
<br/>
confirm Password:
<br/>
<input type="password" name="password2" />
<br/>
<input class ="btn btn-primary" type="submit" value= "signup" />
<br/>
</form>
</div>
</html>
My urls.py:
from django import views
from django.urls import path
from .views import SignUp, SignIn, Index
urlpatterns = [
path('', Index.as_view(), name='Index'),
path('signup', SignUp.as_view(), name='SignUp'),
path('signin/', SignIn.as_view(), name='SignIn')
]
Related
Having issue with redirecting, I am at registration page("accounts/register") on my website where I want if someone register then a verification code will send on his email id and to verify we have a url "accounts/verify". but when I am trying to register it register a user but does not send them on "accounts/verify" instead it send that to "accounts/register/accounts/verify" ,
Also please let me know how to use user email address, while registering him into database. I just want his email id to send verification code.
Here is my URL.py of my app:
from django.contrib import admin
from django.urls import path,include
from . import views
from django.contrib.auth.models import User
urlpatterns = [
path('login/', views.login, name='Login-Page'),
path('register/', views.register, name='Registeration-page'),
path('logout/', views.logout),
path('verify/', views.verify, name='verification page')
Here is my View.py for registration and profile:
from django.shortcuts import render, redirect
import requests
from django.contrib.auth.models import User, auth
from django.contrib import messages
from datetime import date
import smtplib
import random
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
def register(request):
if request.method == 'POST':
first_name = request.POST['first_name']
last_name = request.POST['last_name']
username = request.POST['username']
email = request.POST['email']
password1 = request.POST['password1']
password2 = request.POST['password2']
if password1==password2:
if User.objects.filter(username=username).exists():
messages.info(request, "Username already taken")
return redirect('accounts/register')
elif User.objects.filter(email=email).exists():
messages.info(request, "email already taken")
return redirect('accounts/register')
else:
user = User.objects.create_user(username=username, password=password1, email=email, first_name=first_name, last_name=last_name)
user.save();
return redirect('accounts/verify') # 'accounts/login'
else:
messages.info(request,"password not matched")
return redirect('accounts/register')
else:
return render(request, 'register.html')
def verify(request):
if request.method == 'POST':
sender_address = 'xyz#gmail.com'
sender_pass = 'password'
user_email = register.user.objects.email
receiver_address = user_email
passd = random.randrange(111111,10000000,39)
mail_content = "Hello This is your verficatiob code " + str(passd)
def check(code):
if code==passd:
return redirect('accounts/login')
else:
messages.info(request,"Code is incorrect")
return redirect('accounts/verify')
message = MIMEMultipart()
message['From'] = sender_address
message['To'] = receiver_address
message['Subject'] = 'Verification Code'
message.attach(MIMEText(mail_content, 'plain'))
session = smtplib.SMTP(EMAIL_HOST, EMAIL_PORT)
session.starttls()
session.login(sender_address, sender_pass)
text = message.as_string()
session.sendmail(sender_address, receiver_address, text)
session.quit()
print('Mail Sent')
code = request.POST['code']
check(code)
else:
return render(request, 'email_verify.html')
Here is my register template:
<div class="limiter">
<div class="container-login100" style="background-image: url ('/images/bg-01.jpg');">
<div class="wrap-login100 p-l-55 p-r-55 p-t-65 p-b-54">
<form action="{{register}}" method="post">
{% csrf_token %}
<!--<form class="login100-form validate-form">-->
<span class="login100-form-title p-b-49">
Registration
</span>
<div>
{% for message in messages %}
<input class="wrap-input validate-input m-b-23" data-validate="{{message}}">
{% endfor %}
</div>
<div class="wrap-input100 validate-input m-b-23" data-validate = "First name is reauired">
<span class="label-input100"><th>first name</th></span>
<input class="input100" type="text" name="first_name" placeholder="Type your First name">
<span class="focus-input100" data-symbol=""></span>
</div>
<div class="wrap-input100 validate-input m-b-23" data-validate = "Last name is reauired">
<span class="label-input100"><th>last name</th></span>
<input class="input100" type="text" name="last_name" placeholder="Type your Last name">
<span class="focus-input100" data-symbol=""></span>
</div>
<div class="wrap-input100 validate-input" data-validate="Username is required">
<span class="label-input100">Username</span>
<input class="input100" type="username" name="username" placeholder="Type your username">
<span class="focus-input100" data-symbol=""></span>
</div>
<div class="wrap-input100 validate-input" data-validate="email is required">
<span class="label-input100">email</span>
<input class="input100" type="email" name="email" placeholder="Type your email">
<span class="focus-input100" data-symbol=""></span>
</div>
<div class="wrap-input100 validate-input" data-validate="password is required">
<span class="label-input100">Password</span>
<input class="input100" type="password" name="password1" placeholder="Type your password">
<span class="focus-input100" data-symbol=""></span>
</div>
<div class="wrap-input100 validate-input" data-validate="confirm password is required">
<span class="label-input100">Confirm Password</span>
<input class="input100" type="password" name="password2" placeholder="Type your password Again">
<span class="focus-input100" data-symbol=""></span>
</div>
<br>
<div class="container-login100-form-btn">
<div class="wrap-login100-form-btn">
<div class="login100-form-bgbtn"></div>
<button class="login100-form-btn">
Register
</button>
</div>
</div>
</form>
</div>
</div>
</div>
This is the error:
Page not found (404)
Request Method: GET
Request URL: localhost/accounts/register/accounts/verify
Using the URLconf defined in made.urls, Django tried these URL patterns, in this order:
admin/
[name='Homepage']
accounts/ login/ [name='Login-Page']
accounts/ register/ [name='Registeration-page']
accounts/ logout/
accounts/ verify/ [name='verification page']
from django.contrib import admin
from django.urls import path,include
from . import views
from django.contrib.auth.models import User
urlpatterns = [
path('login/', views.login, name='Login-Page'),
path('register/', views.register, name='Registeration-page'),
path('logout/', views.logout),
path('verify/', views.verify, name='verificationPage')
#
def verify(request):
if request.method == 'POST':
sender_address = 'xyz#gmail.com'
sender_pass = 'password'
user_email = register.user.objects.email
receiver_address = user_email
passd = random.randrange(111111,10000000,39)
mail_content = "Hello This is your verficatiob code " + str(passd)
def check(code):
if code==passd:
return redirect('accounts/login')
else:
messages.info(request,"Code is incorrect")
return HttpResponseRedirect(reverse('verificationPage')) # you'r issus
#Or return HttpResponseRedirect("/Yourapp/verify")
message = MIMEMultipart()
message['From'] = sender_address
message['To'] = receiver_address
message['Subject'] = 'Verification Code'
message.attach(MIMEText(mail_content, 'plain'))
session = smtplib.SMTP(EMAIL_HOST, EMAIL_PORT)
session.starttls()
session.login(sender_address, sender_pass)
text = message.as_string()
session.sendmail(sender_address, receiver_address, text)
session.quit()
print('Mail Sent')
code = request.POST['code']
check(code)
else:
return render(request, 'email_verify.html')
If you don't add /(slash) to beginnig of URL like how you did in return redirect('accounts/verify'), it will be added on current URL and you will unfortunately will be redirected to "accounts/register/accounts/verify" which is not defined. You need to change all like return redirect('/accounts/verify'). Or, my advice is representing them by their name. In this case, it would be return redirect('verification page').
And here is how I could send an email, a bit different from your way. But it worked fine on my project.
settings.py
EMAIL_BACKEND ="django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = "smtp.gmail.com"
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = "youremailadress#gmail.com"
EMAIL_HOST_PASSWORD = "yourpassword"
views.py
from django.core.mail import send_mail
send_mail("subject","message", EMAIL_HOST_USER, ["recipient#gmail.com"])
Do you have any security concerns with what I've done being implemented in a production web app? Either in the Django HTML Template or my views logic?
I would prefer to have the form in actual html rather than using {{ form }}. Is it ok to allow the user to implement very basic passwords?
views.py is:
from django.shortcuts import render, redirect
from django.contrib.auth import get_user_model
User = get_user_model()
from django.contrib.auth import authenticate, login as auth_login
from django.contrib import auth
from memberships.models import UserMembership
from django.contrib.auth.decorators import login_required
from companies.models import Profile
# Create your views here.
def register(request):
if request.method == "POST":
# User has info and wants an account now!
if request.POST['password1'] == request.POST['password2']:
try:
user = User.objects.get(email=request.POST['email'])
return render(request, 'accounts/register.html', {'error': 'Email has already been taken'})
except User.DoesNotExist:
user = User.objects.create_user(request.POST['email'], password=request.POST['password1'])
auth.login(request, user)
company = Profile()
company.businessperson = request.user
company.first_name = request.POST['firstname']
company.last_name = request.POST['lastname']
company.company_name = request.POST['companyname']
company.phone_number = request.POST['phonenum']
company.save()
return redirect('memberships:payment')
else:
return render(request, 'accounts/register.html', {'error': 'Passwords must match'})
# User wants to enter info
return render(request, 'accounts/register.html')
def login(request):
if request.method == "POST":
user = authenticate(email=request.POST["email"], password=request.POST["password"])
if user is not None:
# Our backend authenticated the credentials
auth_login(request, user)
return redirect('dashboard')
else:
# Backend did not authenticate the credentials
return render(request, 'accounts/login.html', {"error": "Incorrect email and or password"})
else:
return render(request, 'accounts/login.html')
def logout(request):
if request.method == "POST":
auth.logout(request)
return redirect('login')
forms in login.html and register.html:
<!-- login.html -->
<form action="{% url 'login' %}" method="POST">
{% csrf_token %}
<div class="form-group">
<input type="email" name="email" id="exampleInputEmail">
</div>
<div class="form-group">
<input type="password" name="password" id="exampleInputPassword" >
</div>
<input type="submit" value="Login">
</form>
<!-- register.html -->
<form action="{% url 'register' %}" method="POST" >
{% csrf_token %}
<input type="text" name="firstname" id="exampleFirstName" >
<input type="text" name="lastname" id="exampleLastName" >
<input type="text" name="companyname" id="exampleInputCompany" >
<input type="tel" name="phonenum" id="exampleInputPhone" placeholder="Phone Number">
<input type="email" name="email" id="exampleInputEmail" placeholder="Email" required>
<input type="password" name="password1" id="exampleInputPassword" placeholder="Password" required>
<input type="password" name="password2" id="exampleRepeatPassword" placeholder="Repeat Password" required>
<input type="submit" value="Register Account">
</form>
Good day,
Using Django 1.11, I have created signin and signup forms.
My signin form is working correctly, but my signup form is using the GET method, not the POST method specified. Using the inspector on the signin form, it just shows . The method="POST" action="...." are missing and I cannot see why.
urls.py:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'signin/$', views.sign_in, name='signin'),
url(r'signup/$', views.sign_up, name='signup'),
url(r'signout/$', views.sign_out, name='signout'),
]
views.py
def sign_in(request):
form = AuthenticationForm()
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
if form.user_cache is not None:
user = form.user_cache
if user.is_active:
login(request, user)
return HttpResponseRedirect(
reverse('stb:home')
)
else:
messages.error(
request,
"That user account has been disabled."
)
else:
messages.error(
request,
"Username or password is incorrect."
)
return render(request, 'stb/signin.html', {'form': form})
def sign_up(request):
form = UserCreationForm()
if request.method == 'POST':
form = UserCreationForm(data=request.POST)
if form.is_valid():
# Unpack form values
username = form.cleaned_data['username']
password = form.cleaned_data['password1']
email = form.cleaned_data['email']
# Create the User record
user = User(username=username, email=email)
user.set_password(password)
user.save()
user = authenticate(
username=username,
password=password
)
login(request, user)
messages.success(
request,
"You're now a user! You've been signed in, too."
)
return HttpResponseRedirect(reverse('stb:profile'))
return render(request, 'stb/signup.html', {'form': form})
signup.html:
{% extends "layout.html" %}
{% block title %}{{ block.super }} | Sign Up{% endblock %}
{% block body %}
<div class="grid-30 centered">
<h2>Sign Up</h2><form>
<form method="POST" action="{% url 'stb:signup' %}">
{% csrf_token %}
<input name="username" id="id_username" required="" autofocus=""
placeholder="User Name" maxlength="150" type="text">
<input name="email" id="id_email" required=""
placeholder="Email Address" type="email">
<input name="password1" required="" id="id_password1"
placeholder="Password" type="password">
<input name="password2" required="" id="id_password2"
placeholder="Confirm Password" type="password">
<input type="submit" class="button-primary" value="Sign Up">
<a class="button" href="signin.html">Sign In</a>
<input type="hidden" name="next" value="{{ next }}" />
</form>
</div>
{% endblock %}
Try moving the form assignment in the first line to the else statement of the if ,
Like this,
def sign_up(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password1']
email = form.cleaned_data['email']
user = User(username=username, email=email)
user.set_password(password)
user.save()
user = authenticate( username=username, password=password )
login(request, user)
messages.success( request, "You're now a user! You've been signed in, too." )
return HttpResponseRedirect(reverse('stb:profile'))
else:
return render(request, 'stb/signup.html', {'errors': form.errors}
else:
form = UserCreationForm ()
return render(request, 'stb/signup.html', {'form': form})
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>
I'm attempting to setup a login using django and bootstrap found here and here
my views.py
def LoginRequest(request):
if request.user.is_authenticated():
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
email = form.cleaned_data['email']
password = form.cleaned_data['password']
user = authenticate(email=email, password=password)
if user is not None:
login(request, user)
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
else:
return render_to_response('/', {'form': form}, context_instance=RequestContext(request))
else:
return render_to_response('/', {'form': form}, context_instance=RequestContext(request))
else:
form = LoginForm()
return render_to_response('/', {'form': form}, context_instance=RequestContext(request))
my urls.py
from core.views import LoginRequest, LogoutRequest, ContactRequest
urlpatterns = patterns('',
url(r'^login/$', 'LoginRequest'),
url(r'^logout/$', 'LogoutRequest'),
my forms.py
class LoginForm(forms.Form):
email = forms.CharField(label=(u'Email'), max_length=30)
password = forms.CharField(label=(u'Password'), widget=forms.PasswordInput(render_value=False), max_length=30)
And the snippet from my index.html -
{% if user.is_authenticated %}
<li><a href={% url 'dashboard' %}>Dashboard</a></li>
{% else %}
<li class="dropdown">
<a class="dropdown-toggle" href="#" data-toggle="dropdown">Login<strong class="caret"></strong></a>
<div class="dropdown-menu" style="padding: 15px; padding-bottom: 10px;">
<form action='/login/' method="POST">
{% csrf_token %}
{% if form.errors %}
{{ form.errors}}
{% endif %}
<label for="id_email">Login:</label>
<input type="text" name="email" id="id_email">
<br />
<label for="id_password">Pass:</label>
<input type="password" name="password" id="id_password">
<br />
<input class="btn btn-primary" type="submit" value="Login" />
<input type="hidden" name="next" value="{{ '/dashboard' }}" />
</form>
</div>
</li>
{% endif %}
As soon as I hit "login" I get the following traceback -
Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
111. response = wrapped_callback(request, *callback_args, **callback_kwargs)
Exception Type: TypeError at /login/
Exception Value: 'unicode' object is not callable
In your urls file, you need to remove the string around the view names.
Like this:
urlpatterns = patterns('',
url(r'^login/$', LoginRequest), #Shred the quotes
url(r'^logout/$', LogoutRequest), #Shred the quotes
Note that the new django recommended way is:
from core import views
urlpatterns = patterns('',
url(r'^login/$', views.LoginRequest),
url(r'^logout/$', views.LogoutRequest),
Also, you can simplify your view like this:
def LoginRequest(request):
redirect_to = request.META.get('HTTP_REFERER', '/')
if request.user.is_authenticated():
return HttpResponseRedirect(redirect_to)
form = LoginForm()
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
email = form.cleaned_data['email']
password = form.cleaned_data['password']
user = authenticate(email=email, password=password)
if user is not None:
login(request, user)
return HttpResponseRedirect(redirect_to)
return render_to_response('/', {'form': form}, context_instance=RequestContext(request))
Also, / needs to be something like: /index.html - depends on where the template is located.