Search code examples
pythonlinuxflaskcsrfauth0

Auth0, flask: Users need to login twice due to CSRF error


When a user logs into my flask app it does not work first time, but it typically works on the second attempt. The following error occurs on the first login attempt:

MismatchingStateError: mismatching_state: CSRF Warning! State not equal in request and response

I did not have this problem when running on localhost on a windows PC. I obtained this problem when moving my code to a linode running ubuntu 20.04. I am considering flask in python3 as well as the following packages.

from flask import Flask
from flask import jsonify
from flask import redirect
from flask import render_template
from flask import session
from flask import url_for
from flask import request
from flask import send_from_directory
from authlib.integrations.flask_client import OAuth

My keys are fixed in a .env file. They are not randomly generated.

oauth = OAuth(app)

auth0 = oauth.register(
    'auth0',
    client_id=AUTH0_CLIENT_ID,
    client_secret=AUTH0_CLIENT_SECRET,
    api_base_url=AUTH0_BASE_URL,
    access_token_url=AUTH0_BASE_URL + '/oauth/token',
    authorize_url=AUTH0_BASE_URL + '/authorize',
    client_kwargs={
        'scope': 'openid profile email',
    },
)

The following code in the callback handling gives the CSRF error.

@app.route('/callback')
def callback_handling():
    auth0.authorize_access_token()
    resp = auth0.get('userinfo')

Solution

  • I may have solved this question by updating my ntp on linux with the help of the following link: https://askubuntu.com/questions/254826/how-to-force-a-clock-update-using-ntp

    apt-get install -y  ntp
    sudo service ntp stop
    sudo ntpd -gq
    sudo service ntp start
    

    I also added a try except in my python server

    try:
            
        auth0.authorize_access_token()
                    resp = auth0.get('userinfo')
        userinfo = resp.json()
        session[constants.JWT_PAYLOAD] = userinfo
        session[constants.PROFILE_KEY] = {
            'user_id': userinfo['sub'],
            'name': userinfo['name'],
            'picture': userinfo['picture'],
            'email_verified':userinfo['email_verified']
        }
    except:
        return redirect("/mainpage") 
    
    #Some code
    
    return redirect('mainpage')
    

    Ensure that the 'mainpage' requires authorisation.