1

How to configure flask app with flask-jwt-extended for which we need something like below.

  1. AccessToken/Bearer must sent as a Header (and not cookie)
  2. RefreshToken must sent as httpOnlyCookie for /api/refreshtoken path only

How to set two different token one in header and one in cookie? We are able to set either both as cookie or both as a header.

Any help?

Thanks Raxit

Raxit Sheth
  • 2,491
  • 5
  • 17
  • 20

1 Answers1

1

I wanted to do the same while building a React + Flask single page application after days of headache trying to understand authorization and authentication as I am a beginner.

Anyways, I managed to do it this way:

In Flask, config:

app.config['JWT_TOKEN_LOCATION'] = ['headers', 'cookies']
app.config['JWT_REFRESH_COOKIE_PATH'] = '/auth/refresh'

And what I return in my login function:

resp = jsonify({'access_token': access_token})
set_refresh_cookies(resp, refresh_token)
return resp, 200

And in my refresh function:

# Refresh access token
@app.route('/auth/refresh', methods=['POST'])
@jwt_refresh_token_required
def refresh():
    user = get_jwt_identity()
    resp = {
        'access_token': create_access_token(
            identity={
                'username': user['username'],
                'role': user['role']
            },
            expires_delta=timedelta(seconds=600),
            user_claims=user['role']
        )
    }
    return jsonify(resp), 200

And on the front side, I collect the JSON access_token and set it in memory and use withCredentials to send the refresh_token with my API calls.

axios.defaults.withCredentials = true;
axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}`;

more precisely:

.then(({ data: { access_token } }) => {
      axiosHttp.defaults.headers.common['Authorization'] = `Bearer ${access_token}`;
      return jwt_decode(access_token);
    })

then I use the data from my decoded access_token in a React Context Component to authenticate access to pages depending on roles.

logout is simply setting to null my context and calling the api to unset the refresh cookie

@app.route('/auth/logout', methods=['DELETE'])
@jwt_required
def logout():
    resp = jsonify({"msg": "Successfully logged out"})
    unset_jwt_cookies(resp)
    return resp, 200

it's quite simple in the end but it took me quite a while to figure out!

dorsk
  • 11
  • 1