I have simple python flask app with flask-login implemented. I have two functions to load template called first.html and second.html both of them are protected by a @login_required decorator. Below is the code I have written
#!/usr/bin/python
from app import app
from flask import render_template,request,redirect,abort
from flask_login import login_required,url_for,login_user,logout_user,LoginManager
from app.models.models import Users
import md5
from itsdangerous import URLSafeTimedSerializer
loginManager = LoginManager()
loginManager.init_app(app)
loginManager.login_view = 'signin'
loginManager.login_message = 'Please log in'
@loginManager.user_loader
def load_user(name):
user = Users.query.get(name)
return user
@loginManager.token_loader
def load_token(token):
print 'In Token Loader'
serializer = URLSafeTimedSerializer(app.secret_key)
data = serializer.loads(token)
username = data[0]
user = Users.query.get(name)
print user
return user
@app.route('/logout')
def logout():
print 'executing logout'
logout_user()
return render_template('login.html')
@app.route('/login',methods=['GET','POST'])
def signin():
if request.method == 'GET':
return render_template('login.html')
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
salted_password = password + app.secret_key
hashedpassword = md5.new(salted_password).hexdigest()
user = Users.query.filter(Users.username == username).first()
if user == None:
return render_template('login.html')
storedPass = user.password
if storedPass == hashedpassword:
login_user(user, remember=True)
nex = request.args.get('next')
return redirect(nex or url_for('first'))
return render_template('login.html')
@app.route('/first')
@login_required
def first():
return render_template('first.html')
@app.route('/second')
@login_required
def second():
return render_template('second.html')
Now I access http://locahost:5000/login and login view is loaded. I entered the valid user and password which is authenticated successfully and gets a redirect to url_for('first')
Since first function is decorated with @login_required I am getting the login page again. As per my understanding from documentation, @token_loader called will be called and it handles the token and loads the first.html but this is not happening and login view is loaded again.
If i remove the @login_required decorator from first function, the the first.html is loaded.
I am missing something in invoking the token validation in my code and I am not sure what it is.
My User data model class looks like below
#!/usr/bin/python
from app import db,app
from itsdangerous import URLSafeTimedSerializer
class Users(db.Document):
uid = db.StringField()
username = db.StringField()
password = db.StringField()
def is_authenticated(self):
return True
def is_active(self):
return True
def is_anonymous(self):
return False
def get_id(self):
return unicode(self.uid)
def get_auth_token(self):
serializer = URLSafeTimedSerializer(app.secret_key)
return serializer.dumps([self.username,self.password])
Thanks