I have been working on a web interface using Flask and having some issues with back button in browser as after logging out hitting it takes user back inside. I have found similar questions and tried their answers but the issue is not resolved. I am attaching a simple example kindly have a look at it.
Main
from flask import Flask, request,session, redirect, url_for, render_template
from os import urandom
app = Flask(__name__)
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
app.secret_key = urandom(24)
#app.route('/', methods=['POST', 'GET'])
def index():
if request.method == 'POST':
session['Email id'] = request.form.get('Email Id')
Pass = request.form.get('Password')
try:
if session['Email id'] == 'KK#gmail.com' and Pass == 'KKK':
return render_template('Logged_in.html')
except:
return render_template('login.html')
return render_template('login.html')
#app.route('/sign_out')
def sign_out():
session.pop('Email id')
return redirect(url_for('index'))
#app.after_request
def add_header(r):
r.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
r.headers["Pragma"] = "no-cache"
r.headers["Expires"] = "0"
r.headers['Cache-Control'] = 'public, max-age=0'
return r
if __name__ == '__main__':
app.run(host="0.0.0.0", debug=True, threaded=True)
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="{{ url_for('index') }}" method="POST" id="login" class="input-group">
<input type="text" class="input-field" placeholder="Email Id" required name="Email Id">
<input type="text" class="input-field" placeholder="Password" required name="Password">
<button type="submit" class="submit-btn" style="color: white;">Log in</button>
</form>
</body>
</html>
Logged_in.html
<h2>You are Logged in</h2>
<i class="fas fa-sign-out-alt"></i>Log out
Your problem is that when users push the back button their browser will re-do the POST request. You need to use the POST/redirect/GET pattern to prevent this. For this you need four endpoints in totalt:
GET / : Check in the session that the user is logged in and render Logged_in.html, otherwise redirect to /login.html
GET /login.html : Render login.html
POST /sign_in : Check username and password. If successful, update the session and redirect to /
POST /sign_out : Log out the user session and redirect to /login.html
Do not render templates in your POST endpoints, just make them manipulate the session and then redirect.
Related
I have this very basic chat app, where everyone can chat in one huge group. And when I send messages, other people have to refresh their web page to see new messages. I am just wondering if anyone has any idea how to do this. By the way, the app is made with python Flask and HTML.
from flask import Flask, render_template, request, url_for, redirect
import database as db
app = Flask(__name__)
app.secret_key = 'ItDoesntMatter'
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'GET':
return render_template('/index.html', messages=db.get_messages())
#Else
message = request.form['message']
db.send_message(message)
return redirect(url_for('index'))
if __name__ == '__main__':
app.run()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chat</title>
</head>
<body>
{% for message in messages %}
<div>At {{ message[1] }}: <strong>{{ message[0] }}</strong></div>
{% endfor %}
<form method="POST" action="/">
<input type="text" placeholder="message" name="message">
<button type="submit" id="btn">Send</button>
</form>
</body>
</html>
I tried to do this with a turbo-flask, but it didn't work. I was also on google for like 1 hour and I didn't find anything.
I have a python flask app with login module implemented using extension python flask. In my login method.
The Error Message
app.py
# import the Flask class from the flask module
from flask import Flask, render_template, redirect, url_for, request, session
# create the application object
app = Flask(__name__)
app.secret_key = "hello"
# use decorators to link the function to a url
##app.route('/')
#def home():
# return "Hello, World!" # return a string
#app.route('/index', methods=['GET'])
def index():
if session.get ('username'):
return render_template('index.html')
else:
return render_template('login.html') # render a template
# route for handling the login page logic
#app.route('/', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or request.form['password'] != 'admin':
error = 'Invalid Credentials. Please try again.'
else:
session['username'] = True
return redirect(url_for('index'))
return render_template('login.html', error=error)
# start the server with the 'run()' method
if __name__ == '__main__':
app.run(debug=True)
login page
login.html
<html>
<head>
<title>Flask Intro - login page</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="container">
<h1>Please login</h1>
<br>
<form action="" method="post">
<input type="text" placeholder="Username" name="username" value="{{
request.form.username }}">
<input type="password" placeholder="Password" name="password" value="{{
request.form.password }}">
<input class="btn btn-default" type="submit" value="Login">
</form>
{% if error %}
<p class="error"><strong>Error:</strong> {{ error }}</p>
{% endif %}
</div>
</body>
</html>
index.html
<DOCTYPE Html>
<html>
<head>
<tile>Addressing a Site</tile>
</head>
<body>
<address>welcome.</address>
</body>
</html>
i am trying to create a session between login and index page,just getting started with python flask framework, login session not working well.
It seems like you are actually having an issue with the methods rather than the session not working.
The Method Not Allowed error means that you are sending a GET/POST request to a page that does not accept that type of request.
Try changing the start of your login form to this
<form action="{{ url_for('login') }}" method="POST">
I just got it running on my computer and this works, the reason it did not work before was because the form was sending the post request to the /index route, which only accepts GET request.
Also, I noticed something else you may want to change.
You currently have this on your index route
if session.get ('username'):
return render_template('index.html')
else:
return render_template('login.html')
But it would be better to change that to this
if session.get ('username'):
return render_template('index.html')
else:
return redirect(url_for('login'))
That way the user is sent back to the login page rather than just being shown the login template from the index page.
I hope all of that helps.
When I try to submit a request from my web form to my flask app I get a HTTP 405 method not allowed.
app.py (Python App code):
# app.py
from flask import Flask, render_template, request, redirect, json, url_for
from flaskext.mysql import MySQL
app = Flask(__name__)
# Database connection info. Note that this is not a secure connection.
app.config['MYSQL_DATABASE_USER'] = 'root'
app.config['MYSQL_DATABASE_PASSWORD'] = ''
app.config['MYSQL_DATABASE_DB'] = 'RamsterDB'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql = MySQL()
mysql.init_app(app)
conn = mysql.connect()
cursor = conn.cursor()
mysql = MySQL()
mysql.init_app(app)
conn = mysql.connect()
cursor = conn.cursor()
#app.route('/')
def main():
return render_template('search.html')
#app.route('/showRegister', methods=['POST','GET'])
def showRegister():
return render_template('register.html')
#app.route('/register', methods=['POST, GET'])
def register():
# read the posted values from the UI
#try:
_username = request.form['inputUsername']
_password = request.form['inputPassword']
# validate the received values
if _username and _password:
return json.dumps({'html': '<span>All fields good !!</span>'})
else:
return json.dumps({'html': '<span>Enter the required fields</span>'})
#return render_template('register.html')
if __name__ == '__main__':
app.debug = True
app.run()
register.html (Registration page code):
<!DOCTYPE html>
<html lang="en">
<head>
<title>Ramster</title>
<link rel="stylesheet" href="/static/index.css">
<script src="/static/js/jquery-1.11.2.js"></script>
<script src="../static/js/register.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, height=100%">
</head>
<body>
<div class="topnav">
Login
Register
</div>
<div class="content">
<h2>Ramster</h2>
<p>Register your team</p>
<form class="example" method="post" action="" style="margin:left;max-width:600px">
<input type="text" name="inputUsername" id="inputUsername" placeholder="Username" required autofocus><br><br><br>
<input type="text" name="inputPassword" id="inputPassword" placeholder="Password" required><br><br><br>
<button id="btnRegister" class="example" type="submit">Register</button>
</form>
<!--<form class="example" method="post" action="" style="margin:left;max-width:600px">
<input type="text" placeholder="Username" name="inputUsername">
<input type="text" placeholder="Password" name="inputPassword">
<button type="submit">Register</button>
</form>
<p></p>-->
</div>
<div class="footer">
<p>Terms and Conditions</p>
</div>
</body>
</html>
register.js:
$(function() {
$('#btnRegister').click(function() {
$.ajax({
url: '/register',
data: $('form').serialize(),
type: 'POST',
success: function(response) {
console.log(response);
},
error: function(error) {
console.log(error);
}
});
});
});
error in browser:
jquery-1.11.2.js:9659 POST http://localhost:5000/register 405 (METHOD NOT ALLOWED)
I have tried changing the form parameters as well as the Python code, but nothing seems to be working. I have not attempted to connect to MySQL yet until I fix the 405 issue. I have tried to find an answer but cannot find one anywhere.
You have list with single element instead of list with 2 elements.
Replace
#app.route('/register', methods=['POST, GET'])
with
#app.route('/register', methods=['POST', 'GET'])
I have been developing a system but I recently have not been able to debug why I get this error
Method Not Allowed
The method is not allowed for the requested URL.
I have been developing a system
I assume the problem has to do with the post function not being allowed and being interrupted by something please assist me thx.
code:
python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route('/')
def student():
return render_template('index.html')
#app.route('/result',methods = ['POST', 'GET'])
def result():
if request.method == 'POST':
result = request.form['name']
print(result)
return "thank you for filling out this form"
if __name__ == '__main__':
app.run(debug = True)
file_object = open('transferfile.txt', 'a+')
name = "Gabriel"
age = "12"
gender = "male"
file_object.write(name)
file_object.write(" ")
data = file_object.read(100)
file_object.write(age)
file_object.write(" ")
file_object.write(gender)
file_object.close()
html
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>venuefast</title>
</head>
<body>
<form class="logo" action="." method="post">fastvenue<br>
<hr>
<input type ="text" name="name" placeholder="name">
<br>
<button type="submit" value="submit">Submit</button>
</form>
</body>
</html>
Since the student function is rendering the form in index.html, it only makes sense that the student function accepts POST requests:
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route('/',methods = ['POST', 'GET'])
def student():
if request.method == 'POST':
name = request.form['name']
return f"thank you for filling out this form {name}!"
return render_template('index.html')
#app.route('/result')
def result():
return 'this function does nothing yet'
if __name__ == '__main__':
app.run(debug = True)
an alternative, if you are planning to use student for something else, you can make result function renders index.html instead and also make it accept POST requests:
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route('/')
def student():
return 'this function does nothing yet'
#app.route('/result',methods = ['POST', 'GET'])
def result():
if request.method == 'POST':
name = request.form['name']
return f"thank you for filling out this form {name}!"
return render_template('index.html')
if __name__ == '__main__':
app.run(debug = True)
Try This in the HTML
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>venuefast</title>
</head>
<body>
<form class="logo" action="/result" method="POST">
<p>fastvenue</p>
<br>
<hr>
<input type ="text" name="name" placeholder="name">
<br>
<button type="submit" value="submit">Submit</button>
</form>
</body>
</html>
I am trying to write a program that reads a file and outputs it to the textarea. The user can then edit the file and then click the submit button in order to submit the changes.
Currently, I have a method of obtaining the user's input (request.form), however I do not know how to prepopulate the text area element.
Flask
from flask import Flask
from flask import render_template
from flask import request
app = Flask(__name__)
#app.route('/')
def hello():
return render_template("index.html")
#app.route('/', methods=['POST'])
def submit():
return 'You entered: {}'.format(request.form['whitelist'])
if __name__ == '__main__':
app.run(host="localhost", port=8000, debug=True)
HTML
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Index</title>
</head>
<body>
<h1 style="color: blue">Index</h1>
<p>This is an HTML file served up by Flask</p>
<p>Whitelist:</p>
<form action="{{ url_for('submit') }}" method="post">
<textarea id="whitelist" name="whitelist" rows="4" cols="50"></textarea>
<input type="submit">
</form>
</body>
</html>
So is their a method that exists such that one can prepopulate the textarea?
Example
my_file_data = read_my_file(file)
Flask.output(element_id = "whitelist", input = my_file_data)
Implementing Solution
Try the following changes in your code (i assume that your file is a .txt but it can work with other file types with some changes):
Flask
#app.route('/')
def hello():
with open('your_file') as f:
t=f.read()
return render_template("index.html", t=t)
HTML
<textarea id="whitelist" name="whitelist" rows="4" cols="50"> {{t}} </textarea>