FastAPI extension that provides JWT Auth support (secure, easy to use, and lightweight)

Overview

FastAPI JWT Auth

Tests Coverage Status PyPI version Downloads


Documentation: https://indominusbyte.github.io/fastapi-jwt-auth

Source Code: https://github.com/IndominusByte/fastapi-jwt-auth


Features

FastAPI extension that provides JWT Auth support (secure, easy to use and lightweight), if you were familiar with flask-jwt-extended this extension suitable for you, cause this extension inspired by flask-jwt-extended 😀

  • Access tokens and refresh tokens
  • Freshness Tokens
  • Revoking Tokens
  • Support for WebSocket authorization
  • Support for adding custom claims to JSON Web Tokens
  • Storing tokens in cookies and CSRF protection

Installation

The easiest way to start working with this extension with pip

pip install fastapi-jwt-auth

If you want to use asymmetric (public/private) key signing algorithms, include the asymmetric extra requirements.

pip install 'fastapi-jwt-auth[asymmetric]'

License

This project is licensed under the terms of the MIT license.

Comments
  • Websocket Support

    Websocket Support

    Currently it looks as though websockets wont work with the standard require_jwt_auth() even when sent via cookies (which works with flask_jwt_extended). This is the error I'm getting:

    ERROR:    Exception in ASGI application
    Traceback (most recent call last):
      File "/home/user/dev/work/venv/lib/python3.8/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 154, in run_asgi
        result = await self.app(self.scope, self.asgi_receive, self.asgi_send)
      File "/home/user/dev/work/venv/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
        return await self.app(scope, receive, send)
      File "/home/user/dev/work/venv/lib/python3.8/site-packages/fastapi/applications.py", line 179, in __call__
        await super().__call__(scope, receive, send)
      File "/home/user/dev/work/venv/lib/python3.8/site-packages/starlette/applications.py", line 111, in __call__
        await self.middleware_stack(scope, receive, send)
      File "/home/user/dev/work/venv/lib/python3.8/site-packages/starlette/middleware/errors.py", line 146, in __call__
        await self.app(scope, receive, send)
      File "/home/user/dev/work/venv/lib/python3.8/site-packages/starlette/exceptions.py", line 58, in __call__
        await self.app(scope, receive, send)
      File "/home/user/dev/work/venv/lib/python3.8/site-packages/starlette/routing.py", line 566, in __call__
        await route.handle(scope, receive, send)
      File "/home/user/dev/work/venv/lib/python3.8/site-packages/starlette/routing.py", line 283, in handle
        await self.app(scope, receive, send)
      File "/home/user/dev/work/venv/lib/python3.8/site-packages/starlette/routing.py", line 57, in app
        await func(session)
      File "/home/user/dev/work/venv/lib/python3.8/site-packages/fastapi/routing.py", line 228, in app
        await dependant.call(**values)
      File "./backend/api/routers/apps.py", line 171, in dashboard
        Authorize.jwt_required()
      File "/home/user/dev/work/venv/lib/python3.8/site-packages/fastapi_jwt_auth/auth_jwt.py", line 670, in jwt_required
        self._verify_and_get_jwt_in_cookies('access',self._decode_issuer)
      File "/home/user/dev/work/venv/lib/python3.8/site-packages/fastapi_jwt_auth/auth_jwt.py", line 541, in _verify_and_get_jwt_in_cookies
        cookie = self._request.cookies.get(cookie_key)
    AttributeError: 'NoneType' object has no attribute 'cookies'
    
    enhancement 
    opened by SelfhostedPro 27
  • How to retrieve current user from request.headers while ratelimiting the endpoint?

    How to retrieve current user from request.headers while ratelimiting the endpoint?

    For ratelimiting the endpoint I want to use two approaches i)based on IP address (unprotected endpoint, no JWT access token)

    def get_remote_address(request: Request) -> str:
        """
        Returns the ip address for the current request (or 127.0.0.1 if none found)
        """
        return request.client.host or "127.0.0.1"
    

    It works fine

    2 ) based on current user, current user has to be retrieved from JWT access token. JWT access token is created using this fastapi-jwt-auth and user is in get-jwt-subject.

    from starlette.requests import Request
    from fastapi_jwt_auth import AuthJWT
    
    def get_user_from_headers(request: Request):
        if 'authorization' in request.headers:
            
            current_user = AuthJWT.get_jwt_subject()
            print(current_user)
            return current_user
        else:
             return  get_remote_address
    

    Doing this, I couldn't find current-user. How to find current_user if request.headers has authorization?

    opened by himalacharya 17
  • Personalization exeption messages

    Personalization exeption messages

    Hi, how can i personalize exeption messages?

    @app.exception_handler(AuthJWTException) def authjwt_exception_handler(request: Request, exc: AuthJWTException): return JSONResponse( status_code=exc.status_code, content={"detail": exc.message} )

    opened by MohammadmahdiAhmadi 6
  • Add enable setting to options

    Add enable setting to options

    Would it be feasible to add an optional option to enable or disable authentication to the jwtSettings?

    Currently I'm using Fast-API users (but I'm migrating to fastapi-jwt-auth) and one of the requests of some users is to be able to disable authentication (so that they can use their own authentication platform like authelia).

    With FastAPI users I highjack a function (essentially if the DISABLE_AUTH environment variable is set to true, I import a fake function that just returns true instead of the actual get_active_user function (code here)).

    I was wondering if there's a similar way to do that with this framework?

    opened by SelfhostedPro 5
  • How can I use it in graphql?

    How can I use it in graphql?

    Is it possible to use it in graphql? https://fastapi.tiangolo.com/advanced/graphql/

    Tried this: https://github.com/tiangolo/fastapi/issues/1279

    But it's not showing the graphiql ide : {"detail":"Method Not Allowed"}

    opened by amiyatulu 4
  • Freshness Tokens docs: fresh=False

    Freshness Tokens docs: fresh=False

    In https://indominusbyte.github.io/fastapi-jwt-auth/usage/freshness/

    def refresh():
        new_access_token = Authorize.create_access_token(subject=current_user,fresh=False)
    

    fresh=False. Took me a while to figure out on localhost why it was giving me the "Fresh token required" error. Switching this to True got me good. I'm a total JWT newb, and still wrapping my mind around it, so maybe it's user-error on my part?

    opened by lefnire 4
  • Print AuthJWTException message

    Print AuthJWTException message

    While testing protected endpoint, I put wrong access token (deleting some values in actual access token) in Postman. I tired to print AuthJwt exception but it gives nothing. When I donot supply access token, no any exception message is printed. For example: access token is eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

    But I put access token in Postman as eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJz to test It gives nothing while printing print(e).

    except AuthJWTException as e:
           print(e)
           return ErrorResponseModel(
                            "Something went wrong",
                            status.HTTP_200_OK,
                            status.HTTP_401_UNAUTHORIZED
                        )   
    

    Code in main.py

    application.add_exception_handler(AuthJWTException, authjwt_exception_handler)
    

    How toc check individual exception?

    opened by himalacharya 4
  • Invalid token type. Token must be a <class 'bytes'>

    Invalid token type. Token must be a

    Hi. I've got this problem. How to fix this?

    Request to get access token: curl -H "Content-Type: application/json" -X POST -d '{"email":"test","password":"test"}' http://localhost:8000/login Response: {"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0IiwiaWF0IjoxNjA0MzUwMTc4LCJuYmYiOjE2MDQzNTAxNzgsImp0aSI6IjI5Yjg3YTY0LTQyZDQtNGVlZC1iZmEyLTU4OTZhZjdhNjM2NiIsImV4cCI6MTYwNDM1MTA3OCwidHlwZSI6ImFjY2VzcyIsImZyZXNoIjpmYWxzZX0.o6JkaCJmANVbuwaj5loHmj_YBLfHchf8TiTssdwmgTM", "refresh_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0IiwiaWF0IjoxNjA0MzUwMTc4LCJuYmYiOjE2MDQzNTAxNzgsImp0aSI6IjY5NTc1MjBhLTFiNDItNDFhOS1iMmRmLWZmNTU2ODBhNDIyYiIsImV4cCI6MTYwNjk0MjE3OCwidHlwZSI6InJlZnJlc2gifQ.SVa5ol5sDGzcUnDtrf--oduG5jifapXYy2zulwt6fO0"}

    Request to protected endpoint with Authorize.jwt_required: curl -H "Authorization: Authorization-Token eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0IiwiaWF0IjoxNjA0MzUwMTc4LCJuYmYiOjE2MDQzNTAxNzgsImp0aSI6IjI5Yjg3YTY0LTQyZDQtNGVlZC1iZmEyLTU4OTZhZjdhNjM2NiIsImV4cCI6MTYwNDM1MTA3OCwidHlwZSI6ImFjY2VzcyIsImZyZXNoIjpmYWxzZX0.o6JkaCJmANVbuwaj5loHmj_YBLfHchf8TiTssdwmgTM" http://localhost:8000/protected Response: {"detail":"Invalid token type. Token must be a <class 'bytes'>"}

    opened by NazarKostetskiy 4
  • Sliding sessions

    Sliding sessions

    I really appreciate your work on this project.

    It could be a nice feature to have sliding sessions available, i.e. sending fresh access tokens on every request, if a certain time of inactivity is not exceeded.

    Some information about this approach can be found here https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/.

    Any suggestions how this could be implemented? Maybe as a middleware?

    Best regards

    opened by hestal 3
  • Custom Token checker function not working

    Custom Token checker function not working

    I try to separate the logic of checking JWT tokens from one function so that it can be reused. But when I try to run the code, it does not work. I manage an access token in my database and check if it exists or not. The last generated token will be valid only for the access token. This access token must be checked at every protected endpoint. Here is my code:

    
    @router.get('/user')
    async def items(Authorize: AuthJWT = Depends(), db: AsyncIOMotorClient = Depends(get_database)):
        try:
            await jwt_token_checker(Authorize, db)
            return {"asd"}   
    
        except Exception as ex:
            return error
    

    Helper Function:

    async def jwt_token_checker( Authorize: AuthJWT , conn: AsyncIOMotorClient):
        try:
            Authorize.jwt_required()
            jti = Authorize.get_raw_jwt()['jti']
            current_user = Authorize.get_jwt_subject()
            access_token_check = await check_access_token(conn, Authorize, jti, current_user)
            
            errorMessage = ""
            if access_token_check == AuthEnum.FORBIDDEN_UNAUTHORIZED_ACCESS:
                errorMessage = Locale(
                    language, strings.FORBIDDEN_UNAUTHORIZED_ACCESS).string
                return errorMessage
        except Exception as ex:
            return error
    

    Is this right way to separate the token checker function? If not then can you please suggest me some solution.

    opened by techxonia 3
  • Support for RSA base encryption

    Support for RSA base encryption

    Hi, for RSA base encryption there is a public key that is used to decrypt messages. By the look of it, the library does not seem to support this. Would it make sense to add support for it ?

    opened by m4nuC 3
  • Fetching CSRF from headers requires update

    Fetching CSRF from headers requires update

    In this line, https://github.com/IndominusByte/fastapi-jwt-auth/blob/a6c06193319da0e4976c7472966f3a2891e0d50c/fastapi_jwt_auth/auth_jwt.py#L549 the code is trying to get CSRF_TOKEN from the headers and treating response.headers as a dict object which is true. But the headers don't contain the default "X-CSRF-Token". It contains the key-value pair with cookies as key and all cookie info as a string separated by ;.

    So whenever someone tries to get CSRF token the code is unable to find the key "X-CSRF-Token" in the headers but now it's inside key cookies, which needs to be parsed for extracting CSRF_TOKEN.

    That's why whenever someone uses csrf_protect as True, they get a Missing CSRF Token error every time

    I can see the code is not updated for the last 2 years. That might be the reason that it is not in compliance with the browser's headers.

    opened by shivam221098 0
  • create refresh and access token together

    create refresh and access token together

    now it can create an access token and refresh token together with a specific id that "aid" so in deny list we can block both of them, by blocking that is the same in both

    opened by Alima12 1
  • OpenApi docs

    OpenApi docs

    I'm having a problem with the OpenApi doc generation, I tested https://indominusbyte.github.io/fastapi-jwt-auth/advanced-usage/generate-docs/ and it keeps giving the error with the Authorization key being ignored by openApi, if you make the call via insomnia it works normally

    Att

    opened by wesleymr59 0
  • AttributeError: 'str' object has no attribute 'decode'

    AttributeError: 'str' object has no attribute 'decode'

    I am using pyjwt version 2.4.0 and I think it's conflicting and showing this error: AttributeError: 'str' object has no attribute 'decode' When I try to use this:

    access_token = self.authorize.create_access_token(subject=body.phone)
    refresh_token = self.authorize.create_refresh_token(subject=body.phone)
    

    When I down grade pyjwt to 1.7.0 it works fine.

    opened by sombek 1
  • Fixed a grammatical error in the docs

    Fixed a grammatical error in the docs

    A grammatical error was observed in the docs. It said "Which keeps javascript cannot be able to access the cookies."

    I think want was meant was "Which means javascript cannot be able to access the cookies."

    opened by VictoryIfebhor 0
Releases(v0.5.0)
  • v0.5.0(Nov 6, 2020)

  • v0.4.0(Nov 2, 2020)

  • v0.3.0(Oct 29, 2020)

    • (Deprecated) environment variable support
    • Change name function load_end() -> load_config()
    • Change name function get_jwt_identity() -> get_jwt_subject()
    • Change name identity claims to standard claims sub (Thanks to @rassie for suggestion)
    • Additional headers in claims
    • Get additional headers claims from request or parsing token directly
    • Leeway exp claim decode token
    • Dynamic token expires time
    • Change name blacklist -> denylist
    • Denylist custom check refresh and access tokens
    • Issuer claim
    • Audience claim
    • Jwt decode algorithms
    • Dynamic algorithm create token
    • Token multiple location
    • Support RSA encryption (Thanks to @jet10000 for make issues)
    • Custom header name and type
    • Custom error message key and status code
    • JWT in cookies (Thanks to @m4nuC for make issues)
    • Add Additional claims
    • Add Documentation (#9 by @paulussimanjuntak)
    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Oct 7, 2020)

    • Call create_token and get_jti function must be from dependency injection
    • Improve blacklist loader
    • Can load env from pydantic
    • Add docs on readme how to use without dependency injection and example on multiple files
    • Fix raise jwt exception PR #1 by @ironslob
    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Aug 13, 2020)

    • Access token and refresh token
    • Token freshness will only allow fresh tokens to access endpoint
    • Token revoking/blacklisting
    • Custom token revoking
    Source code(tar.gz)
    Source code(zip)
Owner
Nyoman Pradipta Dewantara
Security enthusiast and Python 🐍 enthusiast | CTF PLAYER
Nyoman Pradipta Dewantara
Pingo provides a uniform API to program devices like the Raspberry Pi, BeagleBone Black, pcDuino etc.

Pingo provides a uniform API to program devices like the Raspberry Pi, BeagleBone Black, pcDuino etc. just like the Python DBAPI provides an uniform API for database programming in Python.

Garoa Hacker Clube 12 May 22, 2022
Imia is an authentication library for Starlette and FastAPI (python 3.8+).

Imia Imia (belarussian for "a name") is an authentication library for Starlette and FastAPI (python 3.8+). Production status The library is considered

Alex Oleshkevich 91 Nov 24, 2022
RSA Cryptography Authentication Proof-of-Concept

RSA Cryptography Authentication Proof-of-Concept This project was a request by Structured Programming lectures in Computer Science college. It runs wi

Dennys Marcos 1 Jan 22, 2022
python implementation of JSON Web Signatures

python-jws 🚨 This is Unmaintained 🚨 This library is unmaintained and you should probably use For histo

Brian J Brennan 57 Apr 18, 2022
Connect-4-AI - AI that plays Connect-4 using the minimax algorithm

Connect-4-AI Brief overview I coded up the Connect-4 (or four-in-a-row) game in

Favour Okeke 1 Feb 15, 2022
Easy and secure implementation of Azure AD for your FastAPI APIs 🔒 Single- and multi-tenant support.

Easy and secure implementation of Azure AD for your FastAPI APIs 🔒 Single- and multi-tenant support.

Intility 220 Jan 05, 2023
Corsair_scan is a security tool to test Cross-Origin Resource Sharing (CORS).

Welcome to Corsair_scan Corsair_scan is a security tool to test Cross-Origin Resource Sharing (CORS) misconfigurations. CORS is a mechanism that allow

Santander Security Research 116 Nov 09, 2022
Python library for generating a Mastercard API compliant OAuth signature.

oauth1-signer-python Table of Contents Overview Compatibility References Usage Prerequisites Adding the Library to Your Project Importing the Code Loa

23 Aug 01, 2022
:couple: Multi-user accounts for Django projects

django-organizations Summary Groups and multi-user account management Author Ben Lopatin (http://benlopatin.com) Status Separate individual user ident

Ben Lopatin 1.1k Jan 09, 2023
A Python tool to generate and refresh Amazon access tokens.

amazon_auth A Python tool to generate and refresh Amazon access tokens. Description This tool generates and outputs Amazon access and refresh tokens f

15 Nov 21, 2022
Flask App With Login

Flask App With Login by FranciscoCharles Este projeto basico é o resultado do estudos de algumas funcionalidades do micro framework Flask do Python. O

Charles 3 Nov 14, 2021
A wagtail plugin to replace the login by an OAuth2.0 Authorization Server

Wagtail OAuth2.0 Login Plugin to replace Wagtail default login by an OAuth2.0 Authorization Server. What is wagtail-oauth2 OAuth2.0 is an authorizatio

Gandi 7 Oct 07, 2022
Basic auth for Django.

easy-basicauth WARNING! THIS LIBRARY IS IN PROGRESS! ANYTHING CAN CHANGE AT ANY MOMENT WITHOUT ANY NOTICE! Installation pip install easy-basicauth Usa

bichanna 2 Mar 25, 2022
🔐 Login & Register System

🔐 Login & Register System This is a developable login and register system. Enter your username and password to register or login to account. Automati

Firdevs Akbayır 10 Dec 12, 2022
Google Auth Python Library

Google Auth Python Library This library simplifies using Google's various server-to-server authentication mechanisms to access Google APIs. Installing

Google APIs 598 Jan 07, 2023
Authentication for Django Rest Framework

Dj-Rest-Auth Drop-in API endpoints for handling authentication securely in Django Rest Framework. Works especially well with SPAs (e.g React, Vue, Ang

Michael 1.1k Jan 03, 2023
JSON Web Token Authentication support for Django REST Framework

REST framework JWT Auth Notice This project is currently unmaintained. Check #484 for more details and suggested alternatives. JSON Web Token Authenti

José Padilla 3.2k Dec 31, 2022
A simple Boilerplate to Setup Authentication using Django-allauth 🚀

A simple Boilerplate to Setup Authentication using Django-allauth, with a custom template for login and registration using django-crispy-forms.

Yasser Tahiri 13 May 13, 2022
Plotly Dash plugin to allow authentication through 3rd party OAuth providers.

dash-auth-external Integrate your dashboards with 3rd parties and external OAuth providers. Overview Do you want to build a Plotly Dash app which pull

James Holcombe 15 Dec 11, 2022
A Python library for OAuth 1.0/a, 2.0, and Ofly.

Rauth A simple Python OAuth 1.0/a, OAuth 2.0, and Ofly consumer library built on top of Requests. Features Supports OAuth 1.0/a, 2.0 and Ofly Service

litl 1.6k Dec 08, 2022