I'm using Ajax to login, using Flask-Login extension. Here's my server side code:
@app.route('/login', methods=["POST"])
def login():
if current_user.is_authenticated:
redirect_url = url_for('index')
return jsonify(loggedIn=True, redirectUrl=redirect_url)
username = request.form.get('username', '').strip()
password = request.form.get('password', '').strip()
user = User.query.filter_by(username=username).first()
if user and util.encrypt_password(password, user.salt) == user.password:
logged_in_user = CurrentUser(user)
login_user(logged_in_user)
redirect_url = url_for('index')
return jsonify(loggedIn=True, redirectUrl=redirect_url)
else:
return jsonify(loggedIn=False, error='Invalid Email/Password')
and my client side code:
(function(){
$login_form = $('#login_form');
//add validation to form
if( $login_form.length ){
$login_form.parsley()
$login_form.submit(function(e) {
var url = $(this).attr('action');
var data = $(this).serialize();
tryLogin(url, data);
return false;
});
}
function tryLogin(url, data){
var $submitBtn = $('#login_form__submit');
//notify user that we are working
$submitBtn.addClass('btn--loading');
$.ajax({
type: 'POST',
url: url,
data: data,
dataType: 'json',
success: function (data) {
if (data.loggedIn) {
mixpanel.track('login_success');
window.location.href = data.redirectUrl || '/';
}
}
});
}
});
Not sure what's wrong, I have started seeing this problem lately, and it fails more than 50% of times. In case of failure, it'll just redirect to the new page but no session info exist. All the content is hosted on the same domain.
EDIT:
More info: even when the login doesn't work intermittently, the backend does pass the login and frontend receives loggedIn=True and redirectUrl. Seems like issue is with session/cookie being received by the client but not sure why the intermittent issue.
UPDATE
Wholever is reading this now. I couldn't find a good solution. But debugged and realized this was definitely happening due to some bug in Chrome to update cookie/session data from the Ajax request. I resolved this by moving to server-side sessions using redis instead of client side. That made sure the request always have the right session info.