I am trying to implement enter to personal account on my web app in Flask.
Scheme is as follows:
'login'
and 'password'
and hit entervalidate_user()
executes after than which after database request return true or falseuser_login()
The problem is in the last step, when redirect to /personal_account does not properly work and URL does not change and js does not connect and instead of private.html there is code of page where user was when he tries to enter to personal account (button enter_to_account is on every page of flask app)
private.html
{% block tab_content %}
<canvas width="800" height="600" id="canvas"></canvas>
<script>
window.onload = init;
function init(){
console.log('работает');
var canvas = document.getElementById('canvas');
if (canvas) {
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.fillRect(25, 25, 100, 100);
}
}
}
</script>
{% endblock %}
function validate_user()
@app.route('/validate_user', methods=['POST'])
def validate_user():
login = request.form['login']
password = request.form['password']
try:
c, conn = cursor_connection()
c = conn.cursor()
c.execute("SELECT hsh "
"FROM auth_info "
"WHERE login='{}' ; "
"".format(login, password))
res = c.fetchall()[0][0]
c.close()
conn.close()
except Exception as e:
logger.info(msg='Failed to execute /validate_user {}'.format(e))
return render_template('500.html')
if check_password_hash(password=password, pwhash=res):
return jsonify({'result': True})
return jsonify({'result': False})
function user_login()
@app.route('/user_login', methods=['POST'])
def user_login():
login = request.form['login']
if login is None or not login:
return jsonify(data='Incorrect URL')
try:
c, conn = cursor_connection()
c = conn.cursor()
c.execute("SELECT accounts_info_uid "
"FROM auth_info WHERE login='{}' ".format(login))
id = c.fetchall()
if not id:
return jsonify(data='Incorrect login')
c.execute("SELECT * FROM boxes_id AS tb1 LEFT JOIN"
" accounts_info AS tb2 ON tb2.boxes_ids=tb1.uid "
# "LEFT JOIN electricity_info as tb3 ON tb3.boxes_id_uid=tb1.uid"
" WHERE tb2.uid={} ".format(id[0][0]))
uid, mc_address, working_status, activation_status, _,\
first_name, second_name, registration_date, phone, email, boxes_id = c.fetchall()[0]
c.execute(" SELECT consumed_electricity "
"FROM electricity_info "
"WHERE boxes_id_uid={} ".format(boxes_id))
consumed_electricity = [float(val[0]) for val in c.fetchall()]
c.close()
conn.close()
except Exception as e:
logger.error(msg='Cannot execute /user_login {}'.format(e))
return str(e)
user = User()
user.id = login
login_user(user)
return redirect(url_for('welcome'))
welcome page:
@app.route('/welcome')
def welcome():
return render_template('private.html')#'You are on welcome page'
Used tech: flask, python 2.7, jinja2, ajax
Please tell me what is the issue here and how to handle it?
Thank you!
EDIT ONE
code of double-ajax request
common.js:
document.getElementById('next_in').onclick = function (){ //after hitting enter
$.ajax({
data: {
login: document.getElementById('log').value,
password: document.getElementById('pass').value
},
type: 'POST',
url: '/validate_user',
success: function (data_1) {
if(data_1.result==true){
$.ajax({
data: {
login: document.getElementById('log').value
},
type: 'POST',
url: '/user_login',
success: function (data_2) {
document.body.innerHTML = data_2;
}
});
}
else{
alert('Incorrect user or login!');
}
}
});
}
plot inside of private.html:
<script>
window.onload = init;
function init(){
console.log('работает');
var canvas = document.getElementById('canvas');
if (canvas) {
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.fillRect(25, 25, 100, 100);
}
}
}
</script>
EDIT TWO
Allow myself to clarify wanted result once again.
I want redirect to 'pure' private.hrml as well as redirect to 'pure' URL /welcome
答案 0 :(得分:1)
This is not how you authenticate a user. You should never trust the client with anything regarding the auth, and here you basically verify the database response in your Javascript code. Not to mention the private.html
page, which is right now accessible at the /welcome
endpoint without any checks at all: try typing http://localhost:5000/welcome
in your browser if you're using the default Flask settings.
You might find helpful this SO post, which gives an overview of the typical cookie auth.
The Flask-Login library (which you actually have installed) provides some of the most common session management functions.
That being said, if you want to “make it work” with a simple one-page restricted area, here's what you might do:
/welcome
/welcome
, verify and output data in a single request.Example implementation:
from flask import *
app = Flask(__name__)
def verify(login, password) -> bool:
"""Query the database and return True iff there is
a user record with matching credentials. """
return True
def get_user_data(login) -> dict:
"""Query the database for consumed electricity from user. """
return {
'first_name': 'User',
'last_name': 'McUser',
'consumed_electricity': 100.0
}
@app.route('/')
def root():
return render_template('index.html')
@app.route('/welcome', methods=['POST'])
def welcome():
login = request.form['login']
password = request.form['password']
if not verify(login, password):
abort(403)
data = get_user_data(login)
return render_template('private.html', data=data)
index.html
source:
<form action="/welcome" method="post">
Login: <input type="text" name="login"> <br>
Password: <input type="password" name="password"> <br>
<input type="submit" value="Log In">
</form>
private.html
source:
<ul>
<li>{{ data.first_name }}</li>
<li>{{ data.last_name }}</li>
<li>{{ data.consumed_electricity }}</li>
</ul>