Quick Start

There are some complete (but simple) examples available in the examples directory of the Flask-Identity repo.

Danger

The examples below place secrets in source files. Never do this for your application especially if your source code is placed in a public repo. How you pass in secrets securely will depend on your deployment model - however in most cases (e.g. docker, lambda) using environment variables will be the easiest.

Basic SQLAlchemy Application

SQLAlchemy Install requirements

$ mkvirtualenv <your-app-name>
$ pip install flask-identity flask-sqlalchemy

SQLAlchemy Application

The following code sample illustrates how to get started as quickly as possible using Flask-SQLAlchemy and the built-in model mixins:

import os

from flask import Flask, render_template_string
from flask_sqlalchemy import SQLAlchemy
from flask_identity import IdentityManager, auth_required, hash_password, UserMixin, RoleMixin

# Create app
app = Flask(__name__)
app.config['DEBUG'] = True

# Generate a nice key using secrets.token_urlsafe()
app.config['SECRET_KEY'] = os.environ.get("SECRET_KEY", '2HF_R3JddWTLu0zJ1kSV-w')
# Bcrypt is set as default SECURITY_PASSWORD_HASH, which requires a salt
# Generate a good salt using: secrets.SystemRandom().getrandbits(128)
app.config['IDENTITY_HASH_SALT'] = os.environ.get("IDENTITY_HASH_SALT", '2HF_R3JddWTLu0zJ1kSV_hash$salt_')
app.config['IDENTITY_DATASTORE_ADAPTER']='sqlalchemy'

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
# As of Flask-SQLAlchemy 2.4.0 it is easy to pass in options directly to the
# underlying engine. This option makes sure that DB connections from the
# pool are still valid. Important for entire application since
# many DBaaS options automatically close idle connections.
app.config["SQLALCHEMY_ENGINE_OPTIONS"] = {
    "pool_pre_ping": True,
}

# Create database connection object
db = SQLAlchemy(app)

# Define models

class BaseModel(db.Model):
  __abstract__ = True

  id = db.Column(db.Integer, primary_key=True, autoincrement=True)

class Role(db.Model, RoleMixin):
    pass

class User(db.Model, UserMixin):
    pass

# Setup Flask-Identity
identity = IdentityManager(app, db=db, user_model=Users, role_model=Roles)

# Create a user to test with
@app.before_first_request
def init():
  datastore = identity.datastore
  admin = datastore.find_user(username='admin')
  role = datastore.find_role(name='admin')
  if admin is None:
      admin = datastore.create_user(**{'username': 'admin', 'password': hash_password('123456'), 'display': 'Admin'})
  if role is None:
      role = datastore.create_role(**{'name': 'admin', 'display': 'Admin'})

  if admin and not admin.has_roles('admin'):
      datastore.add_role_to_user(admin, role)

# Views
@app.route("/")
@auth_required()
def home():
    return render_template_string("Hello {{ current_user.display }}")

if __name__ == '__main__':
    app.run()