How to resolve form resubmission? - django

When page refresh that post request, form resubmission happened.
I tried redirect after post request. but, it's not working when request have context. this context have form.errors because login.html show form error.
How to resolve this issue? (without Message Framework)
def do_login(request):
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 redirect(reverse('root'))
else:
pass
# redirect cannot pass context, right?
else:
form = LoginForm()
context = {
'form': form
}
return render(request, 'accounts/login.html', context=context)

Your code is using the standard approach. You are redirecting after a successful post request, but not after an unsuccessful post. This allows the form to be displayed with errors.
If the user refreshes after an unsuccessful post, then the browser will usually warn the user that their data will be resubmitted. If they do resubmit, then it doesn't really matter, the login will fail again, and they will see the same errors as before.

Related

unable to implement basic login in the django framework

I am trying as hard as I can to learn to concept of authentication within the Django framework. I am reading the documentation and trying to code similar which will help me get the subject. At the moment I am trying to implement a simple login which redirects to a page. If the user is logged in he should see a message other wise he should see a different message. This is my code.
I have made a simple login form
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput())
this is my login view
def login_view(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('/users/success/')
else:
return redirect('/users/success/')
else:
form = LoginForm()
return render(request, 'testauth/login.html', {'form': form})
(I know the above code is a little bit redundant ... at the moment this is not so important)
and this is the success view
def success_view(request):
print(request.user)
if request.user.is_authenticated:
return HttpResponse("logged in")
else:
return HttpResponse("you are not logged in")
The problem is, I always get the "logged in" message even with users which do not exist. I tried restarting the server my cache is disabled ... I have no idea why is this happening. Why is this happening?
(p.s. I do not want to set in the settings.py a login success url. I want to do everything manually because I am struggling a lot with this topic and I want to make sure that I truly understand everything)

Django csrf_protect decorator not working

I am using Django to build a web app. I am using Vue JS for the frontend. My problem is when ever I use csrf_protect its showing 403 error
My views:
#csrf_protect
def SignUpView(request):
if request.method == "POST":
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
username, password = form.cleaned_data.get('username'), form.cleaned_data.get('password1')
new_user = authenticate(username = username, password = password)
login(request, new_user)
return redirect('/')
else:
form = SignUpForm()
return render(request, 'Accounts/SignUp.html', {'form':form})
#csrf_protect
def validateUsername(request):
username = request.GET.get('username', None)
usernameRegEx = r'^[a-zA-Z0-9#+-_.#]*$'
usernameRegExResult = {
'valid' : bool(re.search(usernameRegEx, username, re.M|re.I)),
'is_taken' : User.objects.filter(username=username).exists()
}
return JsonResponse(usernameRegExResult)
I read the Django docs which says I can use csrf_protect decorator above my view but in my case its not working. Somebody please help.
CSRF is a protection that prevents cross site request forgery. It works by generating an unique token that identify the form. So if you send data to your server without the token it gave you (through cookies for instance) it will not accept it.
If you have the CSRF middleware turned on you should not need CSRF protect decorator!

Where to signal 'wrong password' in this signin view?

I am working on a sign in page in Django, but I am using Userena. I have attached the view method for the signin in Userena below. The problem is that since all the views I have written previously to this were MUCH shorter and concise. I'm having trouble trying to figure out where in this method I would add something in to "do something if password is wrong". Ideally, what I would like to do is if the password is wrong, trigger a popup in javascript. I'm guessing I first have to add something to this view method that indicates the password is wrong though?
#secure_required
def signin(request, auth_form=AuthenticationForm,
template_name='userena/signin_form.html',
redirect_field_name=REDIRECT_FIELD_NAME,
redirect_signin_function=signin_redirect, extra_context=None):
form = auth_form()
if request.method == 'POST':
form = auth_form(request.POST, request.FILES)
if form.is_valid():
identification, password, remember_me = (form.cleaned_data['identification'],
form.cleaned_data['password'],
form.cleaned_data['remember_me'])
user = authenticate(identification=identification,
password=password)
if user.is_active:
login(request, user)
if remember_me:
request.session.set_expiry(userena_settings.USERENA_REMEMBER_ME_DAYS[1] * 86400)
else: request.session.set_expiry(0)
if userena_settings.USERENA_USE_MESSAGES:
messages.success(request, _('You have been signed in.'),
fail_silently=True)
#send a signal that a user has signed in
userena_signals.account_signin.send(sender=None, user=user)
# Whereto now?
redirect_to = redirect_signin_function(
request.REQUEST.get(redirect_field_name), user)
return HttpResponseRedirect(redirect_to)
else:
return redirect(reverse('userena_disabled',
kwargs={'username': user.username}))
if not extra_context: extra_context = dict()
extra_context.update({
'form': form,
'next': request.REQUEST.get(redirect_field_name),
})
return ExtraContextTemplateView.as_view(template_name=template_name,
extra_context=extra_context)(request)
check user present or not like :
if user:
if user.is_active:
login(request,user)
else:
# account disabled
else:
#invalid login detailed
return response

Django auth backends and auto login

I'm trying to have a user login automatically as soon as they register. They have just input their desired username and two matching passwords and I would like to grant access to the site with no more friction. But my current view with an authenticate followed by a login using authenticate's user object doesn't work i.e. the view redirects to the profile page after register, but the profile page is #login_required decorator protected, and so redirects because the login was unsuccessful. I have widely debugged and looked around.
I've tried everything I can think of short of resorting to a third-party registration app. People have suggested there's a problem/peculiarity with the backends or something, but I just can't see why I can't register, auth and login in one view.
views.py (relevant parts)
#login_required
def user(request, user_id):
profile_user = User.objects.get(id=user_id)
context = RequestContext(request)
context['profile_user'] = profile_user
return render_to_response('profile.html', context)
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
new_user = form.save()
new_user = authenticate(username = request.POST['username'],
password = request.POST['password1'])
if new_user is not None:
login(request, new_user)
context = RequestContext(request)
context['user_id'] = new_user.id
context['new_user'] = new_user
url = '/user/%s/' % new_user.id
return HttpResponseRedirect(url)
else:
form = UserCreationForm()
return render_to_response("registration/register.html", {'form': form},
context_instance=RequestContext(request))
How do you deal with this?
You can make it work by:
Redirecting to an intermediate template through simple view, it will set the session cookie on client side, you can show a message like "Registration completed. logging in..."
Redirect to profile page after a small 3-5 seconds time out. This time, request will carry authentication cookie, profile page will be accessible.

Django forms always failing

I'm trying to use Django's built in authentication modules. For the site I'm working on I want to use email addresses as login names and not just the normal alphanumeric fields they're usually set to. In order to do this I changed all the String fields to Email fields and changed their max length from 30 to 320. My registration code appears to be working fine but not my login code. Here is what I'm using right now:
def login(request):
if request.method == 'POST':
form = AuthenticationForm(request.POST)
if form.is_valid():
return HttpResponse("valid")
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return HttpResponseRedirect("/")
# Redirect to a success page.
else:
return HttpResponse("Disabled Account")
# Return a 'disabled account' error message
else:
return HttpResponse("Invalid Login")
# Return an 'invalid login' error message.
else:
return HttpResponse("%s" % repr(form.errors))
else:
form = AuthenticationForm()
return render_to_response("login.html", {'form': form, }, context_instance=RequestContext(request))
No matter what I submit, form.is_valid() is returning FALSE but form.errors is empty. Any ideas what might be wrong? I think I changed everything over to Email properties so I don't think that's it. Also, in case it changes anything I'm trying to do this on google app engine using djangoappengine.
Sorry, but you cannot use Django's authentication module on top of google app engine. Django uses its own special database backend which is similar to google-app-engine's but is not drop-in compatible.
If you want to do authentication on GAE, you should do it the google-app-engine way:
http://code.google.com/appengine/docs/python/users/