user10800954
user10800954

Reputation:

Store tokens in browser cookies with Flask jwt extended

I know how to create tokens with this library, and also how to put tokens in reponse body:

access_token = create_access_token(identity = token_identity)
refresh_token = create_refresh_token(identity = token_identity)
set_access_cookies({"login": True}, access_token)
set_refresh_cookies({"login": True}, refresh_token)

However, when using it with my flask application, nothing is stored in my browser cookies. Do I need to do something more than use the set_access_cookies or set_refresh_cookies in order to store tokens in cookies?

One example of code:

import logging
from flask import Blueprint, render_template, redirect, url_for, request, current_app as app, jsonify
from flask_login import login_user, logout_user, login_required
from werkzeug.security import generate_password_hash, check_password_hash
from .models import User
from . import db, login_manager, login_serializer, jwt
from flask_jwt_extended import (create_access_token, 
create_refresh_token, jwt_required, jwt_refresh_token_required, get_jwt_identity, get_raw_jwt, set_access_cookies,
set_refresh_cookies, unset_jwt_cookies)


def set_response_cookies(token_identity, resp=None, token_types=["access", "refresh"]):
    """
    Helper function to set cookies 
    """
    logging.warning("Setting cookies")
    token_types.sort()
    if token_types == ["access", "refresh"]:
        access_token = create_access_token(identity = token_identity)
        refresh_token = create_refresh_token(identity = token_identity)
        if not resp:
            resp = jsonify({"access_token": access_token, "refresh_token": refresh_token})
        set_access_cookies(resp, access_token)
        set_refresh_cookies(resp, refresh_token)
        return resp 
    elif token_types == ["access"]:
        access_token = create_access_token(identity = token_identity)
        if not resp:
            resp = jsonify({"access_token": access_token})
        set_access_cookies(resp, access_token)
        return resp 
    elif token_types == ["refresh"]:
        refresh_token = create_refresh_token(identity = token_identity)
        if not resp:
            resp = jsonify({"refresh_token": refresh_token})
        set_refresh_cookies(resp, refresh_token)
        return resp 
    else:
        raise ValueError("Wrong Call to this function")

@auth.route('/signup', methods=['POST'])
def signup_post():
    email = request.form.get('email')
    name = request.form.get('name')
    password = request.form.get('password')

    user = User.objects(email=email) 
    if user:  # Email already exist.  
        return redirect(url_for('auth.signup')), 409
    logging.warning("User not existing")
    new_user = User(email=email, name=name, password=generate_password_hash(password, method='sha256'))
    new_user.save()
    set_response_cookies(email, ["access", "refresh"])
    return redirect(url_for('auth.login')), 200

Upvotes: 2

Views: 11477

Answers (2)

HyperActive
HyperActive

Reputation: 1316

The problem may be client-side instead of server-side. My app uses axios and in order to get it to work for me I had to add axios.defaults.withCredentials = true after importing it in the javascript file:

import axios from 'axios'
axios.defaults.withCredentials = true

Upvotes: 0

Akshay Jain
Akshay Jain

Reputation: 790

You can make use of set_cookie()

Store token in cookie:

from flask import make_response

@app.route('/')
def index():
    response = make_response(render_template(...))
    response.set_cookie('access_token', 'YOUR_ACCESS_TOKEN')
    response.set_cookie('refresh_token', 'YOUR_REFRESH_TOKEN')
    return response

To Retrieve the token from cookie:

from flask import request

@app.route('/')
def index():
    access_token = request.cookies.get('access_token')

In this way you can store the token in a cookie and retrive the token from the cookie.

Upvotes: 3

Related Questions