Captcha verification Python Django - python

I am getting Invalid captcha response for below set up. Contact form worked perfectly fine, I added rule that verifies captcha, I checked secret keys and still getting Invalid Captcha even after solving it. Below is my setup:
views.py
def get_client_ip(request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
return ip
def grecaptcha_verify(request):
response = {}
data = request.POST
captcha_rs = data.get('g-recaptcha-response')
url = "https://www.google.com/recaptcha/api/siteverify"
params = {
'secret': settings.RECAPTCHA_SECRET_KEY,
'response': captcha_rs,
'remoteip': get_client_ip(request)
}
verify_rs = requests.get(url, params=params, verify=True)
verify_rs = verify_rs.json()
response["status"] = verify_rs.get("success", False)
response['message'] = verify_rs.get('error-codes', None) or "Unspecified error."
return response
def contact(request):
if request.method == 'POST':
if grecaptcha_verify(request) == "success":
subject = request.POST.get('subject')
message = request.POST.get('message')
email = request.POST.get('email')
if subject and message and email:
try:
send_mail(subject, message, email, ['myemail#gmail.com'],fail_silently= True)
except BadHeaderError:
return HttpResponse('{Bad Header}')
return greatsuccess(request)
else:
return HttpResponse('{Invalid Form}')
else:
return HttpResponse('Invalid Captcha')
return render(request, 'personal/contact.html')
My template:
<div class="form-area">
<form role="form" method="POST">
{% csrf_token %}
<input type="text" class="form-control" id="subject" name="subject" placeholder="Subject" maxlength="70" required>
</div>
<br>
<div class="form-group">
<input type="email" class="form-control" id="email" name="email" placeholder="Email" required>
</div>
<div class="form-group">
<textarea class="form-control" type="textarea" id="message" name="message" placeholder="Message" maxlength="300" rows="7"></textarea>
</div>
<button type="submit" name="submit" class="btn btn-m btn-secondary">Submit</button>
<script src='https://www.google.com/recaptcha/api.js'></script>
<div class="g-recaptcha" data-sitekey="MYKEY"></div>
</form>
I am quite new to Python, how to check what is happening in the background and at which point verification fails?

You are making get request for verification, but you need to make post request to it. That is why captcha verification failing. So try like this:
url = "https://www.google.com/recaptcha/api/siteverify"
headers = {'User-Agent': 'DebuguearApi-Browser',}
params = {'secret': settings.RECAPTCHA_SECRET_KEY, 'response': captcha_rs}
verify_rs = requests.post(url, data=params, headers=headers) # <-- Update Here
... # rest of your code
Please see the documentation on how to verify recaptcha.

Ok.
I got it working. Thanks Ruddra for all the help.
I deleted first </div> as I've noticed this was unnecessary. This allowed g-recaptcha-response to be included in POST data. Apparently it's important to make sure your form is correct and google likes it.
Secondly I did some modifications to main views.py as per advice I received+ some improvements.
def greatsuccess(request):
messages.success(request, "Email sent!")
return render(request, 'personal/contact.html')
def greatfail(request):
messages.error(request, "Invalid Captcha!")
return render(request, 'personal/contact.html')
def grecaptcha_verify(request):
data = request.POST
captcha_rs = data.get('g-recaptcha-response')
url = "https://www.google.com/recaptcha/api/siteverify"
headers = {'User-Agent': 'DebuguearApi-Browser',}
params = {'secret': settings.RECAPTCHA_SECRET_KEY, 'response': captcha_rs}
verify_rs = requests.post(url,params, headers=headers)
verify_rs = verify_rs.json()
response = verify_rs.get("success", False)
return response
def contact(request):
if request.method == 'POST':
response=grecaptcha_verify(request)
if response == True :
subject = request.POST.get('subject')
message = request.POST.get('message')
email = request.POST.get('email')
if subject and message and email:
try:
send_mail('Sent from mywebsite '+subject, message, email, ['email#gmail.com'],fail_silently= True)
except BadHeaderError:
return HttpResponse('{Bad Header}')
return greatsuccess(request)
else:
return HttpResponse('{Invalid Form}')
else:
greatfail(request)
return render(request, 'personal/contact.html')
My template:
<form method="POST">
{% csrf_token %}
<input type="text" class="form-control" id="subject" name="subject" placeholder="Subject" maxlength="70" required>
<br>
<div class="form-group">
<input type="email" class="form-control" id="email" name="email" placeholder="Email" required>
</div>
<div class="form-group">
<textarea class="form-control" type="textarea" id="message" name="message" placeholder="Message" maxlength="300" rows="7"></textarea>
</div>
<div class="g-recaptcha" data-sitekey="key"></div>
<button type="submit" name="submit" class="btn btn-m btn-secondary">Submit</button>
</form>
{% for message in messages %}
{{ message }}
{% endfor %}

Related

Multivaluedict key error wventhough i have set name to input field

I have made a form and set method=post and while taking request.post['name'] to a variable MultiValueDictKeyError is Coming why is that ?
<form action="verify_user" method="post">
{% csrf_token %}
<input required type="text" placeholder="Name" name="name"><br><br>
<input required type="password" placeholder="Password" name="password"><br><br>
<input required type="passord" placeholder="Confirm password" name="confirm_password" id=""> <br><br>
<br><br><h1>{{ messages }}</h1>
<button type="submit">Create</button>
</form>
this is my form ------
def verify_user(request):
inputname = request.POST['name']
inputpass = request.POST['password']
inputconfirmpass = request.POST['confirm_password']
if not inputpass == inputconfirmpass:
messages.info(request,"Passwords don't match")
else:
messages.info(request,"Passwords match")
return redirect('/verify_user')
this is my function in views.py -------------
MultiValueDictKeyError at /verify_user
'name'
Request Method: GET
Request URL: http://127.0.0.1:8000/verify_user
Django Version: 4.1.2
Exception Type: MultiValueDictKeyError
Exception Value: 'name'
this is the error --------
Try to provide another name as name for e.g. person_name something like that, also I'd recommend you to use .get() so that you can also provide some other default value.
views.py:
def verify_user(request):
if request.method=="POST":
inputname = request.POST.get('person_name', False)
inputpass = request.POST.get('password', False)
inputconfirmpass = request.POST.get('confirm_password', False)
if not inputpass == inputconfirmpass:
messages.info(request,"Passwords don't match")
else:
messages.info(request,"Passwords match")
return redirect('/verify_user')
else: # GET request
return render(request, "some_folder_name/your_template.html")
Template file:
<form method="POST">
{% csrf_token %}
<input required type="text" placeholder="Name" name="person_name"><br><br>
<input required type="password" placeholder="Password" name="password"><br><br>
<input required type="passord" placeholder="Confirm password" name="confirm_password" id=""> <br><br>
<br><br><h1>{{ messages }}</h1>
<button type="submit">Create</button>
</form>

error while redirecting one page to other in django

Basically, from and to both page have parameters so how can I redirect to page with parameters?
html page:
{% for vr in adduser.adduser.all %}
<form method="POST" action="{% url 'edituser' id=vr.id bid=adduser.id %}">
{% csrf_token %}
<label for="FirstName">First Name<span style="color:#ff0000">*</span></label>
<input type="text" class="form-control" name="firstname" placeholder="Type FirstName here...." value="{{vr.f_name}}">
<label for="LastName">Last Name<span style="color:#ff0000">*</span></label>
<input type="text" class="form-control" name="lastname" placeholder="Type LastName here...." value="{{vr.l_name}}">
{% endfor %}
<button type="submit" class="btn btn-primary">Add</button>
urls.py
path('edituser/<uid>/<bid>', views.edituser, name="edituser"),
views.py
def edituser(request, uid, bid):
if request.method == "POST":
if request.POST.get('firstname') and request.POST.get('lastname'):
saverecord = AddContact()
saverecord.id = uid
saverecord.f_name = request.POST.get('firstname')
saverecord.l_name = request.POST.get('lastname')
saverecord.save()
viewRecords = AddContact.objects.filter(subscribe='subscribe')
return HttpResponseRedirect(reverse('adduser',bid))
else:
viewRecords = AddContact.objects.filter(subscribe='subscribe')
messages.error(request, "Error During Editing of Contact")
return redirect(request, 'broadcastlist.html')
else:
viewRecords = AddContact.objects.filter(subscribe='subscribe')
messages.error(request, "Error During Editing of Contact")
return redirect(request, 'broadcastlist.html')
To clarify more uid is userid which is for edit the user and bid is broadcast id which is to redirect to the broadcast list.
To redirect to another page in Django with parameters use this
return HttpResponseRedirect(reverse(viewname='the view to which it should redirect', args=(parameters to be passed)))
Use redirect, it's easier than invoking reverse and HttpResponseRedirect directly. (Doc)
from django.shortcuts import redirect
...
return redirect( 'myapp:url_name', urlparam=value, ...)
which is the same as
return HttpResponseRedirect(
reverse( 'myapp:url_name',
kwargs={ 'urlparam': value, ... }
)

error login or password in authentication in flask

I have two forms:
auth.html
<form class="form-signin pt-5" action="/auth/" method="post" >
{% if error_msg: %}
{{ error_msg }}
{% endif %}
<div class="mt-5 form-label-group">
<p class="text-muted">email</p>
<input type="email" id="inputEmail" class="form-control" name = "email" required autofocus>
</div>
<div class="form-label-group">
<p class="text-muted"> password</p>
<input type="password" id="inputPassword" name="password" class="form-control" required>
<label for="inputPassword"></label>
</div>
<div class="checkbox mb-3"></div>
<button class="btn btn-lg btn-danger btn-block" type="submit">Enter</button>
</form>
success form.html
Success
code in flask is:
app = Flask(__name__)
app.secret_key = "randomstring"
app.config["SECRET_KEY"] = "secret_key"
app.config["EMAIL"] = "test#test.ru"
app.config["PASSWORD"] = "test"
#app.route("/auth/", methods=["GET", "POST"])
def auth_open():
error_msg = "" # Пока ошибок нет
if request.method == "POST":
email = request.form.get("username")
password = request.form.get("password")
if ((email and password) and email == app.config["EMAIL"] and password == app.config["PASSWORD"]):
session["is_auth"] = True
return render_template("/")
else:
error_msg = "Error login or password"
return render_template("auth.html", error_msg=error_msg)
When I input password and login it shows me error message instead of success form.How should I solve this problem?
email = request.form.get("email")

Flask always send post request

I have coded the below form and controller but when the page is loaded, the page automatically send request to my database. How to change the form or controller and just send request when I clicked create button.
html code:
<form method="POST" action="/conference/create">
<div class="field">
<div class="control">
<input class="input is-large" type="text" name="name" placeholder="Your Name" autofocus="">
</div>
</div>
<input class="input is-large" type="text" name="shortname" placeholder="Your Shortname">
</div>
</div>
<div class="field">
<div class="control">
<input class="input is-large" type="text" name="year" placeholder="Year">
</div>
</div>
<button class="button is-block is-info is-large is-fullwidth">Create</button>
</form>
</div>
</div>
{% endblock %}
controller function:
#main.route('/conference/create', methods=['POST','GET'])
#login_required
def create_conference():
name = request.form.get('name')
shortname = request.form.get('shortname')
year = request.form.get('year')
startdate = request.form.get('startdate')
enddate = request.form.get('enddate')
submissiondeadline = request.form.get('submissiondeadline')
website = request.form.get('website')
tag = request.form.get('tag')
datem = datetime.today().replace(day=1)
conference = Conference(confid="1", creationdatetime=datem, name=name, shortname=shortname, year=year, startdate=startdate,
enddate=enddate, submissiondeadline=submissiondeadline, creatoruser=12, website=website)
conferenceTag = ConferenceTags("1", tag)
db.session.add(conference)
db.session.commit()
db.session.add(conferenceTag)
db.session.commit()
return render_template('create_conference.html')
By the way, I have changed controller's method parameters with just 'POST' when I do that it gives me not allowed methods error.
you should add an if statement to specify if the incoming request is POST or GET and act accordingly.
if request.method=='GET':
#load page
elif request.method=='POST':
#update database
#main.route('/conference/create', methods=['POST','GET'])
#login_required
def create_conference():
if request.method == 'POST':
name = request.form.get('name')
shortname = request.form.get('shortname')
year = request.form.get('year')
startdate = request.form.get('startdate')
enddate = request.form.get('enddate')
submissiondeadline = request.form.get('submissiondeadline')
website = request.form.get('website')
tag = request.form.get('tag')
datem = datetime.today().replace(day=1)
conference = Conference(confid="1", creationdatetime=datem, name=name, shortname=shortname, year=year, startdate=startdate,
enddate=enddate, submissiondeadline=submissiondeadline, creatoruser=12, website=website)
conferenceTag = ConferenceTags("1", tag)
db.session.add(conference)
db.session.commit()
db.session.add(conferenceTag)
db.session.commit()
return 'you want to do.'
return render_template('create_conference.html')

Django CSRF verification failed even after adding csrf_token tag inside the form html

I'm working on a project using Python(2.7) and Django(1.10) in which I need submit the login form but it returns an error on submission.
Note: I have searched a lot of questions tried various answers but in
most cases the {% csrf_token %} is missing from the <form> HTML
but in my case, I'm using this also, that's why don't mark this
question duplicated, please!
Here's what I have tried:
from form.html:
<form class="fields-signup" action="{% url 'mainlogin' %}" method="post">
{% csrf_token %}
<h1 class="text-center">Sign In</h1>
<div class="form-group">
<input class="user-name form-control" type="text" name="username" placeholder="User name">
</div>
<div class="form-group">
<input class="password form-control" type="password" placeholder="Password" name="password">
</div>
<input type="submit" class="btn siteBtn" value="Sign In">
<!-- <a href="#" class="btn siteBtn" >Sign Up</a>
<p class="text-center">Don’t Have an account? Signup</p> -->
<!--popup-forget-password-->
<div class="col-sm-12">
<button type='button' class="forget-password-btn" data-toggle="modal" data-target="#popUpWindow">Forgot Password</button>
<!--forget-password-end-->
<div class="col-sm-12 register">
<a class="register-driver-btn" data-toggle="modal" data-target="#popUpWindow_register">Register Driver?</a>
</div>
</div>
</form>
from urls.py:
url(r'^$', views.home, name="home"),
from views.py:
if request.method == "GET":
try:
temp = get_template('login.html')
result = temp.render(Context({'context': RequestContext(request)}))
return HttpResponse(result)
more from views.py:
if request.method == "POST":
username = request.POST['username']
# email = request.POST['email']
password = request.POST['password']
try:
#obj = User_table.objects.get(user_name=username, emailid=email)
obj = User_table.objects.get(user_name=username)
if obj:
print('got user obj')
verify_password = ''
try:
verify_password = handler.verify(password, obj.password)
except Exception as e:
print(e)
if verify_password is True:
request.session['user_id'] = obj.id
request.session['user_type'] = obj.user_type
user_name = obj.first_name + ' ' + obj.last_name
request.session['user_name'] = user_name
if not obj.approval_status:
return HttpResponse('Your account is not confirmed by administration.')
obj.is_active = True
obj.login_try = 0
obj.save()
return redirect(home)
else:
try:
# obj = User_table.objects.get(user_name=username, emailid=email)
obj = User_table.objects.get(user_name=username)
if obj:
s = obj.login_try
s = s + 1
obj.login_try = int(s)
if int(obj.login_try) >= 3:
obj.login_try = 3
obj.save()
if int(obj.login_try) == 3:
id = obj.id
key = get_random_string(length=10)
reset_link = 'It seems you forgot password or someone is trying to login you account. This is your password reset link please do not share this with other ' + settings.EMAIL_URL + 'reset_password/' + str(
id) + ' key is : ' + str(key)
send_mail('Reset link', reset_link, settings.EMAIL_HOST_USER, [obj.emailid, ])
obj.password = str(key)
obj.save()
return HttpResponse(
'It seems you forgot password or someone is trying to login you account. Password Reset link has been sent to your email id')
except Exception as e:
print(e)
pass
return redirect(mainlogin)
except Exception as e:
print('error is : ', e)
return HttpResponse('An error has occurred.')
Also, I have included the csrf middleware in my settings.py.
what can be wrong here?
Thanks in advance!
Your problem is here:
if request.method == "GET":
try:
temp = get_template('login.html')
result = temp.render(Context({'context': RequestContext(request)}))
return HttpResponse(result)
Docs about CSRF
In the corresponding view functions, ensure that RequestContext is
used to render the response so that {% csrf_token %} will work
properly. If you’re using the render() function, generic views, or
contrib apps, you are covered already since these all use
RequestContext.
I'm not exactly sure why it's happening, maybe something wrong with context processors configuration, one of them adds csrf_token to context dictionary.
For more debugging see RequestContext section. But using builtin render() function will solve your problem as it'll handle context for you.
from django.shortcuts import render
if request.method == "GET":
...
return render(request, 'login.html')

Categories

Resources