I'm making a text based browser game in python and flask but I encountered a strange problem.
When I try to login on my website I get a "bad request" error.
This is my login route:
#app.route('/login/', methods=['GET','POST'])
def login():
if current_user.is_authenticated:
return redirect("/game/", code=302)
# when the form is filled in
if request.method == 'POST':
# register the user
if request.form['regSubmit'] == 'regSubmit':
username = request.form['regUser']
password = request.form['regPassword']
address = request.form['regAddress']
register_user(username=username,password=password,address=address)
print(address)
return redirect("/login/", code=302)
# login user
if request.form['logSubmit'] == 'logSubmit':
print('lol')
username = request.form['logUser']
password = request.form['logPassword']
result = users.find_one({"user": username})
if result and check_password_hash(result['password'], password):
user_obj = User(result['_id'])
login_user(user_obj)
return redirect("/game/", code=302)
return render_template('out.html')
This is my login modal:
<div id="loginModal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Login</h4>
</div>
<form method="post">
<div class="modal-body">
<p>Please enter your username and password.</p>
<div class="form-group">
<label class="control-label" for="logUser">Username</label>
<input type="text" name="logUser" class="form-control" id="logUser">
</div>
<div class="form-group">
<label class="control-label" for="logPassword">Password</label>
<input type="password" name="logPassword" class="form-control" id="logPassword">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" name="logSubmit" value="logSubmit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>
</div>
</div>
I believe your code is failing because you're trying to access request.form['regSubmit'], but this field does not exist in your form. Accessing any form fields that do not exist will cause Flask to return a 400 Bad Request error.
To get around this, you can either submit your login and register actions to different Flask views, or you can use a try...except block to catch the KeyError generated by trying to access a non-existent form field.
Related
I am trying to execute a form POST request. The request is received at the route api function but the POST condition is not executing.
Code
<form class="pt-2 pb-4" action = "{{ url_for('data_sources_api.testfn') }}" method = "POST">
<div class="row">
<div class="col-md-4 mb-3">
<label for="url" class="form-label">URL</label>
<input type="text" class="form-control" id="url" name="url" aria-describedby="emailHeurllp"
placeholder="Enter new events top domain source url">
</div>
<div class="col-md-4 mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Enter Organization Name">
</div>
<div class="col-md-12">
<button type="button" class="btn btn-secondary mr-2" value="submit" name = "submit">Submit</button>
</div>
</div>
</form>
Flask Code
#data_sources_api.route('/login/test', methods=["GET", "POST"])
def testfn():
# Check if user is loggedin
if loggedin():
# User is loggedin, render the home page
if request.method == 'POST':
print("POST Request Received")
result = request.form
return render_template('users/data-sources.html', role=session['role'])
return redirect(url_for('account_api.login'))
The request received is GET when i click the submit button and not POST :(
Thanks in advance
I think the problem is with button. Replace the button with input type="submit":
<input type="submit" value="Submit">
Here is the example of Django form.
Here is the code for my login form:
<form class="user" action="/returningAgent/" method="post" >
<div class="form-group">
<input type="email" class="form-control form-control-user" id= "InputEmail" name="InputEmail" aria-describedby="emailHelp" placeholder="Enter Email Address...">
</div>
<div class="form-group">
<input type="password" class="form-control form-control-user" id="InputPassword" name="InputPassword" placeholder="Password">
</div>
<div class="form-group">
<div class="custom-control custom-checkbox small">
<input type="checkbox" class="custom-control-input" id="customCheck">
<label class="custom-control-label" for="customCheck">Remember Me</label>
</div>
</div>
<a href="/returningAgent/" class="btn btn-primary btn-user btn-block">
Login
</a>
<hr>
<a href="/returningAgent/" class="btn btn-google btn-user btn-block">
<i class="fab fa-google fa-fw"></i> Login with Google
</a>
<a href="/returningAgent/" class="btn btn-facebook btn-user btn-block">
<i class="fab fa-facebook-f fa-fw"></i> Login with Facebook
</a>
</form>
and here is the code that the form submission triggers:
def returningAgent(request):
#try:
x = Agent.objects.get(bizEmail = request.POST["InputEmail"], password = request.POST["InputPassword"])
diction = {
'f' : x.firstName,
'l' : x.lastName,
'e' : x.bizEmail
}
return render(request, 'index.html', diction)
#except:
#return HttpResponseRedirect('/404/')
I have tried switch request.POST to request.POST.get, and have the name of the field within the HTML form code, yet I still continue to get an error everytime I try to use credentials that are already in my database. Any ideas?
You should update you html form Login a href to button i give
<button type="submit" class="btn btn-primary btn-user btn-block">
Login
</button>
error you actually get in request.POST.get('InputEmail') if you print in your view you get this error because data not getting you use a href in login so it will get request and not actual submit form
and also see get method dictionary produce this error not actually get data if you want get default data when data not pass by request get default value get('key name',default value)
so need to update as i gave in a href to button then let me what's happened
I am basically creating a flask web app which takes username from user and gets his /her codeforces data I am having a problem in extracting the email-id
from the form. I am getting the username but not the email-id.They are both in one form tag in the html file.
Error in browser:
werkzeug.exceptions.HTTPException.wrap..newcls: 400 Bad Request: KeyError: 'email-id'
<form method="POST">
<div class="field">
<label class="label">Username:</label>
<div class="control">
<input class="input" type="text" placeholder="Enter Codeforces username" name="username" value="{{user.handle}}"></input>
</div>
</div>
<div class="has-text-centered">
<input class="button is-link" name="get-info" type="submit" value="Get Info">
</div>
<div class="field">
<label class="label">EMail id:</label>
<div class="control">
<input class="input" type="text" placeholder="Enter mail id" name="email-id" value="">
</div>
</div>
<div class="has-text-centered">
<input class="button is-link" name="get-mail" type="submit" value="Get Mail">
</div>
</form>
#app.route('/',methods=['GET','POST'])
def index():
if request.method == 'POST':
username = request.form['username']
email_id = request.form['email-id']
print(email_id)
print(username)
I am planning to get input from an HTML Form when submitted, the input will be send over to Python. Here is the HTML File
<form method="GET">
<div class="form-inline">
<div class="form-group">
<input type="email" class="line-input" name="userEmail" placeholder="Email">
</div>
<div class="form-group">
<input type="password" class="line-input" name="userPassword" placeholder="Password">
</div>
</div>
<div class="form-inline">
<div class="form-group">
<input type="email" class="line-input" name="recipientMail" placeholder="Recipient">
</div>
<div class="form-group">
<input type="email" class="line-input" name="CCEmail" placeholder="CC">
</div>
</div>
<div class=" form-group">
<button type="submit" class="btn btn-light text-primary btn-block" style="margin : 20px 20px -10px 0px">Send Message</button>
</div>
</form>
Now I don't know the best way to do this, I tried this in Python but doesn't seem to work
#app.route('/', methods=['POST'])
def form_post():
userEmail = request.form['userEmail']
userPassword = request.form['userPassword']
return userEmail, userPassword
Can anyone help me out here?
Change your form method from GET to POST, as your route only specifies "POST", and will not accept any other requests of a different type:
<form method="POST">
Edit: if you wish to specify both methods, ensure that your route checks for the correct type of request currently being sent when the route is triggered:
#app.route('/', methods=['POST','GET'])
def form_post():
if flask.request.method == 'POST'
userEmail = request.form['userEmail']
userPassword = request.form['userPassword']
return userEmail, userPassword
return flask.render_template('something.html')
Note, however, that you are creating your form on the home route ('/'). It may be best to return a link to the page that has the form code:
#app.route('/')
def home():
return 'Welcome! login here'
#app.route('/login', methods=['GET', 'POST']):
if flask.request.method == 'POST'
userEmail = request.form['userEmail']
userPassword = request.form['userPassword']
return flask.redirect('/')
return flask.render_template('form_filename.html')
I have this form and every time I try to post it to the method in the buttom of the Question. The application just gives me a 405 error directly. I have checked that my database works by using the same method in the console.
(I have removed alot of html because it was just styling and stuff like that)
<form action="/register" method="post" class="grid">
<div class="cell colspan3" style="margin-left:2%;">
<div class="input-control modern text">
<input type="email" name="email" id="email">
<span class="label">Email</span>
<span class="informer">Skriv din email</span>
<span class="placeholder">Email</span>
</div>
</div>
<div class="cell colspan3">
<div class="input-control modern text cell">
<input type="text" name="username" id="username" >
<span class="label">Brugernavn</span>
<span class="informer">Skriv dit brugernavn</span>
<span class="placeholder">Brugernavn</span>
</div>
</div>
<div class="cell colspan3">
<div class="input-control modern text cell">
<input type="password" name="password" id="password">
<span class="label">Password</span>
<span class="informer">Skriv dit password</span>
<span class="placeholder">Password</span>
</div>
</div>
<div class="cell colspan3">
<div class="input-control modern text cell">
<input type="password" name="passwordconfirm" id="passwordconfirm">
<span class="label">Gentag password</span>
<span class="informer">Skriv dit password igen.</span>
<span class="placeholder">Gentag password</span>
</div>
</div>
<div class="cell colspan3">
<label class="input-control checkbox ">
<input type="checkbox" name="accept_tos" id="accept_tos">
<span class="check"></span>
<span class="caption">Jeg accepterer hjemmesidens regler</span>
</label>
</div>
<div class="cell colspan3">
<div class="input-control cell">
<button class="button success" type="submit">Registrer</button>
</div>
</div>
</div>
</div>
</form>
The python method that I call with my html post form:
#app.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm(request.form)
if request.method == 'POST' and form.validate():
newUser = User(form.username.data, form.email.data, form.password.data)
db.session.add(newUser)
db.session.commit()
return render_template('login.html')
else:
return render_template('register.html')
And the RegistrationForm method looks like this:
class RegistrationForm(Form):
username = StringField('username', [validators.Length(min=4, max=25)])
email = StringField('email', [validators.email, validators.Length(min=4, max=40)])
password = PasswordField('password',
[validators.Required(),
validators.EqualTo('confirm', message='Passwords skal matche hinanden.')
])
confirm = PasswordField('passwordconfirm')
accept_tos = BooleanField('Jeg accepterer regler for denne hjemmeside', [validators.Required()])
obviously there'snt any problem in these codes unless you have url_prefix for your current app like :
app = Blueprint('user', __name__, url_prefix='/user/')
and u have another blueprint with url_prefix like :
app = Blueprint('general', __name__, url_prefix='/')
with another funtion like :
#app.route('/register', methods=['GET'])
in the blueprint ...
and your form is posting data to '/register' instead of '/user/register'
If that really is the code you're using, I can't see why you're getting a 405 Unsupported Method rather than a validation error. You need to render the hidden CSRF field in the html form.
<form ...>
{{ form.hidden_tag() }}
There are other things wrong with this code. Redirect to login, don't render the template from the register view. Use form.validate_on_submit(). Don't pass request.form to the form. Let the form render the inputs, don't write the html yourself.
Try changing
if request.method == 'POST' and form.validate():
to
if form.validate_on_submit():