All Projects → joegasewicz → Flask Jwt Router

joegasewicz / Flask Jwt Router

Licence: mit
Flask JWT Router is a Python library that adds authorised routes to a Flask app.

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to Flask Jwt Router

Full Stack
Full stack, modern web application generator. Using Flask, PostgreSQL DB, Docker, Swagger, automatic HTTPS and more.
Stars: ✭ 451 (+948.84%)
Mutual labels:  sqlalchemy, flask, jwt
Python Api Development Fundamentals
Develop a full-stack web application with Python and Flask
Stars: ✭ 44 (+2.33%)
Mutual labels:  sqlalchemy, flask, jwt
Flask Restless Security
Concise skeleton for development of Flask, Flask-Restless, SQLAlchemy, JWT based REST APIs.
Stars: ✭ 159 (+269.77%)
Mutual labels:  sqlalchemy, flask, jwt
Potion
Flask-Potion is a RESTful API framework for Flask and SQLAlchemy, Peewee or MongoEngine
Stars: ✭ 484 (+1025.58%)
Mutual labels:  sqlalchemy, flask
Mini Shop Server
基于 Flask 框架开发的微信小程序后端项目,用于构建小程序商城后台 (电商相关;rbac权限管理;附带自动生成Swagger 风格的API 文档;可作「Python 项目毕设」;慕课网系列)---- 相关博客链接:🌟
Stars: ✭ 446 (+937.21%)
Mutual labels:  sqlalchemy, flask
Flask Restplus Boilerplate
A boilerplate for flask restful web service
Stars: ✭ 466 (+983.72%)
Mutual labels:  sqlalchemy, flask
Flask Sqlacodegen
🍶 Automatic model code generator for SQLAlchemy with Flask support
Stars: ✭ 283 (+558.14%)
Mutual labels:  sqlalchemy, flask
Flask Rest Jsonapi
Flask extension to build REST APIs around JSONAPI 1.0 specification.
Stars: ✭ 566 (+1216.28%)
Mutual labels:  sqlalchemy, flask
Fastapi React
🚀 Cookiecutter Template for FastAPI + React Projects. Using PostgreSQL, SQLAlchemy, and Docker
Stars: ✭ 501 (+1065.12%)
Mutual labels:  sqlalchemy, jwt
Open Source Saas Boilerpate
Free SaaS boilerplate (Python/PostgreSQL/ReactJS/Webpack)
Stars: ✭ 582 (+1253.49%)
Mutual labels:  flask, jwt
Flask Sqlalchemy Booster
Collection of utilities and decorators which add extensive querying and serializing capabilities to Flask SQLalchemy models
Stars: ✭ 5 (-88.37%)
Mutual labels:  sqlalchemy, flask
Data Driven Web Apps With Flask
Course demo code and other hand-out materials for our data-driven web apps in Flask course
Stars: ✭ 388 (+802.33%)
Mutual labels:  sqlalchemy, flask
Enferno
A Python framework based on Flask microframework, with batteries included, and best practices in mind.
Stars: ✭ 385 (+795.35%)
Mutual labels:  sqlalchemy, flask
Flask Sqlalchemy
Adds SQLAlchemy support to Flask
Stars: ✭ 3,658 (+8406.98%)
Mutual labels:  sqlalchemy, flask
Mixer
Mixer -- Is a fixtures replacement. Supported Django, Flask, SqlAlchemy and custom python objects.
Stars: ✭ 743 (+1627.91%)
Mutual labels:  sqlalchemy, flask
Databook
A facebook for data
Stars: ✭ 26 (-39.53%)
Mutual labels:  sqlalchemy, flask
Cookiecutter Flask Restful
Flask cookiecutter template for builing APIs with flask-restful, including JWT auth, cli, tests, swagger, docker and more
Stars: ✭ 556 (+1193.02%)
Mutual labels:  flask, jwt
Peeplus
python+vue3前后端分离项目
Stars: ✭ 28 (-34.88%)
Mutual labels:  flask, jwt
Flask Boilerplate
Simple flask boilerplate with Postgres, Docker, and Heroku/Zeit now
Stars: ✭ 251 (+483.72%)
Mutual labels:  sqlalchemy, flask
Safrs
SqlAlchemy Flask-Restful Swagger Json:API OpenAPI
Stars: ✭ 255 (+493.02%)
Mutual labels:  sqlalchemy, flask

Python package PyPI version codecov Codacy Badge Documentation Status PyPI - Python Version GitHub license

Flask JWT Router

Read the docs: Flask-JWT-Router

Flask JWT Router

Flask JWT Router is a Python library that adds authorised routes to a Flask app. Both basic & Google's OAuth2.0 authentication is supported.

Google-Cloud Google's OAuth2.0 supported

Google OAuth 2.0 Quick Start

Read the detailed instructions here: Flask-JWT-Router

oauth_options = {
    "client_id": "<CLIENT_ID>",
    "client_secret": "<CLIENT_SECRET>",
    "redirect_uri": "http://localhost:3000",
    "tablename": "users",
    "email_field": "email",
    "expires_in": 3600,
}

jwt_routes.init_app(app, google_oauth=oauth_options)

Now your front end needs a token. Create an endpoint & return a new access token from the clients header code. For Example::

from flask import request

@app.routes("/login", methods=["POST"])
def login():
    jwt_routes.google.oauth_login(request) # Pass in Flask's request

Now, the next time your front-end requests authorised resources flask-jwt-router will authenticate with this access token until it expires.

Installation

Stable version

pip install flask-jwt-router

Basic Usage

from flask import Flask
from flask_jwt_router import JwtRoutes

app = Flask(__name__)
# You are required to always set a unique SECRET_KEY for your app
app.config["SECRET_KEY"] = "your_app_secret_key"

JwtRoutes(app)

# If you're using the Flask factory pattern:
jwt_routes = JwtRoutes()  # Example with *entity_model - see below

def create_app(config):
   ...
   jwt_routes.init_app(app)

Whitelist Routes

app.config["WHITE_LIST_ROUTES"] = [
    ("POST", "/register"),
]

@app.route("/register", methods=["POST"])
def register():
    return "I don't need authorizing!"

Prefix your api name to whitelisted routes

    # All routes will
app.config["JWT_ROUTER_API_NAME"] = "/api/v1"
app.config["WHITE_LIST_ROUTES"] = [
    ("POST", "/register"),
]

@app.route("/api/v1/register", methods=["POST"])
def register():
    return "I don't need authorizing!"
   

Bypass Flask-JWT-Router on specified routes

    # Define homepage template routes for example on JWT_IGNORE_ROUTES 
    # & still get to use the api name on request handlers returning resources
    app.config["IGNORED_ROUTES"] = [
        ("GET", "/")
    ]

Declare an entity model

# Create your entity model (example uses Flask-SqlAlchemy)
class UserModel(db.Model):
    __tablename__ = "users"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    
# You can define the primary key name with `ENTITY_KEY` on Flask's config
app.config["ENTITY_KEY"] = "user_id"

# (`id` is used by default)
JwtRoutes(app, entity_models=[UserModel, TeacherModel, ...etc])

# Or pass later with `init_app`
def create_app(config):
    ...
    jwt_routes.init_app(app, entity_models=[UserModel, TeacherModel, ...etc])

Authorization

from your_app import jwt_routes

# white list the routes
app.config["WHITE_LIST_ROUTES"] = [
    ("POST", "/register"),
    ("POST", "/login"),
]

@app.route("/login", methods=["POST"])
def register():
    """I'm registering a new user & returning a token!"""
    return jsonify({
        "token": jwt_routes.create_token(entity_id=1, table_name='users')
    })

@app.route("/your_resource", methods=["POST"])
def login():
    """I'm authorized & updating my token!"""
    return jsonify({
        "token": jwt_routes.update_token(entity_id=1)
    })

*Warning: The table_name must be the same as your tablename or __tablename__ attribute's value. (With SqlAlchemy, you can define a __tablename__ attribute directly or else the name is derived from your entity’s database table name).

Setting the Token Expire Duration

There are two ways to set the expire duration of the JWT.

from your app config

        # Set the token expire duration to 7 days
        app.config["JWT_EXPIRE_DAYS"] = 7

calling the set_exp

        # Set the token expire duration to 14 days
        jwt_routes = JwtRoutes()
        # jwt_routes.init_app( ...etc
        jwt_routes.set_exp(expire_days=14)

By default the expire duration is set to 30 days

Create & update Tokens on Routes

Create a new entity & return a new token

@app.route("/register", methods=["POST"])
    def register():
        user_data = request.get_json()
        try:
            user = UserModel(**user_data)
            user.create_user() # your entity creation logic

            # Here we pass the id as a kwarg to `create_token`
            token: str = jwt_routes.create_token(entity_id=user.id, table_name="users")

            # Now we can return a new token!
            return {
                "message": "User successfully created.",
                "token": str(token),  # casting is optional
            }, 200

Access entity on Flask's global context

    from app import app, jwt_routes

    # Example uses Marshmallow to serialize entity object
    class EntitySchema(Schema):
        id = fields.Integer()
        name = fields.String()

    @app.route("/login", methods=["GET"])
    def login():
        user_data = g.get("users") # This is your SqlAlchemy `__tablename__` or the default name.
        try:
            user_dumped = UserSchema().dump(user_data)
        except ValidationError as _:
           return {
                       "error": "User requested does not exist."
                   }, 401
        return {
            "data": user_dumped,
            "token": jwt_routes.update_token(entity_id=user_data.id),
        }, 200
        

If you are handling a request with a token in the headers you can call::

    jwt_routes.update_token(entity_id=user_data.id)

If you are handling a request without a token in the headers you can call::

    jwt_routes.create_token(entity_id=user_data.id, table_name="users")

An Example configuration for registering & logging in users of different types:

    app.config["IGNORED_ROUTES"] = [("GET", "/")]
    app.config["JWT_ROUTER_API_NAME"] = "/api/v1"
    app.config["WHITE_LIST_ROUTES"] = [
        ("POST", "/auth/user"), ("POST", "/auth/user/login"),
        ("POST", "/auth/teacher"), ("POST", "/auth/teacher/login"),
    ]
    
    # Optionally, you can pass your models to Flask's config:
    app.config["ENTITY_MODELS"] = [ UserModel, TeacherModel, ...etc ]

JSON Web Token setup

To send the JSON web token from your front end, you will need to pass a Bearer string in your authorization header. For example:

    fetch(url, {
        headers: {
            Authorization: "Bearer <my_token>",
        }
    })

Routing without headers

If you require calling a resource without passing headers, then you can use the auth query param (useful when streaming video files):

    url = "http://example.com/cars?auth=my_token"

Google OAuth 2.0 with ReactJS

Flask-JWT-Router supports auth Google's OAuth 2.0 Single Sign On strategy if you are using React only. (We will provide Google's OAuth 2.0 Single Sign On strategy for server to server as soon as possible!).

Quick Start

Create a login route for Google's OAuth 2.0

   @app.route("/api/v1/google_login", methods=["POST"])
    def google_login():
        data = jwt_routes.google.oauth_login(request)
        return data, 200

If your app requires multiple redirect uri's then you can use the redirect_uri kwarg to assign a uri for the current request handler. For example:

data = jwt_routes.google.oauth_login(request, redirect="http://another_redirect.com")

We have created a ReactJS library specifically for Flask-JWT-Router - react-google-oauth2.0 In your React app directory install react-google-oauth2.0:

npm install react-google-oauth2 --save 

Testing

Testing OAuth2.0 in a Flask app is non-trivial, especially if you rely on Flask-JWT-Router to append your user onto Flask's global context (or g). Therefore we have provided a utility method that returns a headers Dict that you can then use in your test view handler request. This example is using the Pytest library:

    @pytest.fixture()
    def client():
        # See https://flask.palletsprojects.com/en/1.1.x/testing/ for details


    def test_blogs(client):
        user_headers = jwt_routes.google.create_test_headers(email="[email protected]")
        rv = client.get("/blogs", headers=user_headers)

If you are not running a db in your tests, then you can use the entity kwarg. For example:

# user is an instantiated SqlAlchemy object
user_headers = jwt_routes.google.create_test_headers(email="[email protected]", entity=user)
# user_headers: { "X-Auth-Token": "Bearer <GOOGLE_OAUTH2_TEST>" }

If you require more than one request to a Flask view handler in a single unit test, then set the scope kwarg to application. (Default is function). If you are testing different entities within a single unit test method or function then you must pass in your entity. For example:

my_entity = User(email="[email protected]") # If you're testing against a real db, make sure this is an entry in the db
_ = jwt_routes.google.create_test_headers(email="[email protected]", scope="application", entity=my_entity)

Authors

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

Make sure you have Python versions: 3.6, 3.7, 3.8 Then run:

    tox

To check the docs look good locally you can run:

    make html

License

MIT

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].