Giter Site home page Giter Site logo

2686066876 / fastapi-cloudauth Goto Github PK

View Code? Open in Web Editor NEW

This project forked from tokusumi/fastapi-cloudauth

0.0 1.0 0.0 155 KB

Simple integration between FastAPI and cloud authentication services (AWS Cognito, Auth0, Firebase Authentication).

License: MIT License

Python 98.91% Shell 1.09%

fastapi-cloudauth's Introduction

FastAPI Cloud Auth

Tests codecov PyPI version

fastapi-cloudauth standardizes and simplifies the integration between FastAPI and cloud authentication services (AWS Cognito, Auth0, Firebase Authentication).

Features

  • Verify access/id token: standard JWT validation (signature, expiration), token audience claims and etc.
  • Verify permissions based on scope (or groups) within access token and Extract user info
  • Get the detail of login user info (name, email, etc.) within ID token
  • Dependency injection for verification/getting user, powered by FastAPI
  • Support for:

Requirements

Python 3.6+

Install

$ pip install fastapi-cloudauth

Example (AWS Cognito)

Pre-requirement

  • Check region, userPoolID and AppClientID of AWS Cognito that you manage to
  • Create a user assigned read:users permission in AWS Cognito
  • Get Access/ID token for the created user

NOTE: access token is valid for verification, scope-based authentication and getting user info (optional). ID token is valid for verification and getting full user info from claims.

Create it

Create a file main.py with:

import os
from pydantic import BaseModel
from fastapi import FastAPI, Depends
from fastapi_cloudauth.cognito import Cognito, CognitoCurrentUser, CognitoClaims

app = FastAPI()
auth = Cognito(
    region=os.environ["REGION"], 
    userPoolId=os.environ["USERPOOLID"],
    client_id=os.environ["APPCLIENTID"]
)

@app.get("/", dependencies=[Depends(auth.scope(["read:users"]))])
def secure():
    # access token is valid
    return "Hello"


class AccessUser(BaseModel):
    sub: str


@app.get("/access/")
def secure_access(current_user: AccessUser = Depends(auth.claim(AccessUser))):
    # access token is valid and getting user info from access token
    return f"Hello", {current_user.sub}


get_current_user = CognitoCurrentUser(
    region=os.environ["REGION"], 
    userPoolId=os.environ["USERPOOLID"],
    client_id=os.environ["APPCLIENTID"]
)


@app.get("/user/")
def secure_user(current_user: CognitoClaims = Depends(get_current_user)):
    # ID token is valid and getting user info from ID token
    return f"Hello, {current_user.username}"

Run the server with:

$ uvicorn main:app

INFO:     Started server process [15332]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

Interactive API Doc

Go to http://127.0.0.1:8000/docs.

You will see the automatic interactive API documentation (provided by Swagger UI).

Authorize ๐Ÿ”“ button can be available at the endpoints injected dependency.

You can supply a token and try the endpoint interactively.

Swagger UI

Example (Auth0)

Pre-requirement

  • Check domain, customAPI (Audience) and ClientID of Auth0 that you manage to
  • Create a user assigned read:users permission in Auth0
  • Get Access/ID token for the created user

Create it

Create a file main.py with:

import os
from pydantic import BaseModel
from fastapi import FastAPI, Depends
from fastapi_cloudauth.auth0 import Auth0, Auth0CurrentUser, Auth0Claims

app = FastAPI()

auth = Auth0(domain=os.environ["DOMAIN"], customAPI=os.environ["CUSTOMAPI"])


@app.get("/", dependencies=[Depends(auth.scope(["read:users"]))])
def secure():
    # access token is valid
    return "Hello"


class AccessUser(BaseModel):
    sub: str


@app.get("/access/")
def secure_access(current_user: AccessUser = Depends(auth.claim(AccessUser))):
    # access token is valid and getting user info from access token
    return f"Hello", {current_user.sub}


get_current_user = Auth0CurrentUser(
    domain=os.environ["DOMAIN"],
    client_id=os.environ["CLIENTID"]
)


@app.get("/user/")
def secure_user(current_user: Auth0Claims = Depends(get_current_user)):
    # ID token is valid and getting user info from ID token
    return f"Hello, {current_user.username}"

Try to run the server and see interactive UI in the same way.

Example (Firebase Authentication)

Pre-requirement

  • Create a user in Firebase Authentication and get project ID
  • Get ID token for the created user

Create it

Create a file main.py with:

from fastapi import FastAPI, Depends
from fastapi_cloudauth.firebase import FirebaseCurrentUser, FirebaseClaims

app = FastAPI()

get_current_user = FirebaseCurrentUser(
    project_id=os.environ["PROJECT_ID"]
)


@app.get("/user/")
def secure_user(current_user: FirebaseClaims = Depends(get_current_user)):
    # ID token is valid and getting user info from ID token
    return f"Hello, {current_user.user_id}"

Try to run the server and see interactive UI in the same way.

Additional User Information

We can get values for the current user from access/ID token by writing a few lines.

Custom Claims

For Auth0, the ID token contains extra values as follows (Ref at Auth0 official doc):

{
  "iss": "http://YOUR_DOMAIN/",
  "sub": "auth0|123456",
  "aud": "YOUR_CLIENT_ID",
  "exp": 1311281970,
  "iat": 1311280970,
  "name": "Jane Doe",
  "given_name": "Jane",
  "family_name": "Doe",
  "gender": "female",
  "birthdate": "0000-10-31",
  "email": "[email protected]",
  "picture": "http://example.com/janedoe/me.jpg"
}

By default, Auth0CurrentUser gives pydantic.BaseModel object, which has username (name) and email fields.

Here is sample code for extracting extra user information (adding user_id) from ID token:

from pydantic import Field
from fastapi_cloudauth.auth0 import Auth0Claims  # base current user info model (inheriting `pydantic`).

# extend current user info model by `pydantic`.
class CustomAuth0Claims(Auth0Claims):
    user_id: str = Field(alias="sub")

get_current_user = Auth0CurrentUser(domain=DOMAIN, client_id=CLIENTID)
get_current_user.user_info = CustomAuth0Claims  # override user info model with a custom one.

Or, we can also set new custom claims as follows:

get_user_detail = get_current_user.claim(CustomAuth0Claims)

@app.get("/new/")
async def detail(user: CustomAuth0Claims = Depends(get_user_detail)):
    return f"Hello, {user.user_id}"

Raw payload

If you doesn't require pydantic data serialization (validation), FastAPI-CloudAuth has a option to extract raw payload.

All you need is:

get_raw_info = get_current_user.claim(None)

@app.get("/new/")
async def raw_detail(user = Depends(get_raw_info)):
    # user has all items (ex. iss, sub, aud, exp, ... it depends on passed token) 
    return f"Hello, {user.get('sub')}"

Additional scopes

Advanced user-SCOPE verification to protect your API.

Supports:

  • all (default): required all scopes you set
  • any: At least one of the configured scopes is required

Use as (auth is this instanse and app is fastapi.FastAPI instanse):

from fastapi import Depends
from fastapi_cloudauth import Operator

@app.get("/", dependencies=[Depends(auth.scope(["allowned", "scopes"]))])
def api_all_scope():
    return "user has 'allowned' and 'scopes' scopes"

@app.get("/", dependencies=[Depends(auth.scope(["allowned", "scopes"], op=Operator._any))])
def api_any_scope():
    return "user has at least one of scopes (allowned, scopes)"

Development - Contributing

Please read the CONTRIBUTING how to setup development environment and testing.

fastapi-cloudauth's People

Contributors

tokusumi avatar justinrmiller avatar jurasofish avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.