By default, OAuth access tokens are stored in the Flask session. This means that if the user ever clears their browser cookies, they will have to go through the OAuth flow again, which is not good. You’re better off storing access tokens in a database or some other persistent store.
New in version 0.2.
If you’re using SQLAlchemy, you’ve got a leg up: Flask-Dance has built-in support for this common use case. First, define your model with a token column and a provider column. Flask-Dance includes a OAuthConsumerMixin class to make this easier:
from flask_sqlalchemy import SQLAlchemy
from flask_dance.models import OAuthConsumerMixin
db = SQLAlchemy()
class OAuth(db.Model, OAuthConsumerMixin):
pass
If you have a User model in your application, you can also set up a ForeignKey to your User model:
from flask_sqlalchemy import SQLAlchemy
from flask_dance.models import OAuthConsumerMixin
db = SQLAlchemy()
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
# ... other columns as needed
class OAuth(db.Model, OAuthConsumerMixin):
user_id = db.Column(db.Integer, db.ForeignKey(User.id))
user = db.relationship(User)
Then just pass your OAuth model and your SQLAlchemy session to your blueprint using the set_token_storage_sqlalchemy() method:
blueprint.set_token_storage_sqlalchemy(OAuth, db.session)
Or if you’re using a User model, pass along a reference to the current user so that Flask-Dance can associate users with OAuth tokens. Flask-Login provides a current_user proxy that should work great:
blueprint.set_token_storage_sqlalchemy(OAuth, db.session, user=current_user)
And you should be all set! However, it’s also highly recommended that you use some kind of caching system, to prevent unnecessary load on your database. Since Flask-Dance will automatically load the user’s OAuth token at the start of every request, and since those tokens rarely change, they are prime candidates to be cached. Fortunately, Flask-Dance also integrates with Flask-Cache, which makes caching OAuth tokens trivial. Just pass the cache object along to the set_token_storage_sqlalchemy() method, as well:
from flask_cache import Cache
cache = Cache(app)
blueprint.set_token_storage_sqlalchemy(OAuth, db.session, cache=cache)
And of course, it can also be combined with a User model:
blueprint.set_token_storage_sqlalchemy(OAuth, db.session, user=current_user, cache=cache)
Of course, you don’t have to use SQLAlchemy, you’re free to use whatever storage system you want. To use something else, just write custom get, set, and delete functions, and attach them to the Blueprint object using the token_getter, token_setter, and token_deleter decorators:
@blueprint.token_getter
def get_token():
user = get_current_user()
return user.token
@blueprint.token_setter
def set_token(token):
user = get_current_user()
user.token = token
user.save()
@blueprint.token_deleter
def delete_token():
user = get_current_user()
del user.token
user.save()
Once you set those three functions, you’ll be able to forget about them and just reference token: the functions will be called automatically as needed. Note that Flask-Dance does not handle caching automatically, so you should integrating caching into your custom storage functions! Flask-Cache is very useful for that.