Code Monkey home page Code Monkey logo

fastapi-jwt's Introduction

Hi, I'm Konstantin 👋


🛠️ Tools and Languages

Skills
Data Science NLP badge DL badge XAI badge Pruning badge Compression badge Speech Processing badge CV badge RL badge
Frameworks HuggingFace badge PyTorch badge SkLearn badge Tensorflow badge NLPCore badge TorchText badge
Programming Languages Python badge Rust badge C++ badge CUDA badge GoLang badge
Development Tools git badge Docker badge Neptune.ai badge GitLab-CI badge GitHub-Actions badge Ansible badge ONNX badge
Languages Russian badge English badge German badge Serbian badge

📦 Projects

Project Description Stack
Open Source:
CodeBLEU (2023) Unofficial CodeBLEU metrics implementation as the original does not provide pip package, macOS support and usable interface; Python badge Code badge Code-Generation badge CodeBLEU badge PyPI badge GitHub-Actions badge
Manytask (2023) Auto students' assignments testing system /w gitlab integration; Loaded about 1-2k students per year; Teaching badge Testing badge Python badge LiteStar badge PyTest badge GitHub-Actions badge GitLab-CI badge
fastapi-jwt (2021) FastAPI-native extension for JWT Auth; JWT badge Python badge FastAPI badge PyTest badge
Educational:
EDOS-2023 (2023) Public repo for Sexism Detection Shared Task (EDOS 2023) by LCT-1 team utilising multitasking approach; HuggingFace badge MaChAmp badge multitasking badge Python badge DVC badge
Fact Aware Abstractive Summarization model (2018) Bachelor thesis project, Abstractive Summarization model using Knowledge Graphs - adding additional attention CNN graph encoder for PEGASUS model; PyTorch badge CoreNLP badge FastText badge Summarization badge Python badge
Personal:
Homelab (2023) Personal infrastructure-as-code project for managing my laptop/vps/homeserver with Ansible; Ansible badge Infrastructure-as-Code badge Docker badge GitHub-Actions badge WireGuard badge Linux badge macOS badge
auto-profile (2023) Small project to auto generate github profile, personal website and latex cv using single yaml file; Python badge LaTeX badge markdown badge jinja2 badge GitHub-Actions badge
multi-label-image-classification (2018) Old project for Intel Delta 9 Course final competition - multi label image classification with Inception v3; TensorFlow badge CV badge Python badge

⚡ Github Stats

Github stats Top Lang

fastapi-jwt's People

Contributors

brouberol avatar dependabot[bot] avatar k4black avatar n-ae avatar readyyyk avatar sebsebzen avatar smithk86 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

fastapi-jwt's Issues

Allow audience & issuer to be specified

👋 Hey,

When decoding a JWT, I need to specify an audience and issuer.
Currently I get

Wrong token: Invalid audience

Looking at the code there's no way to pass in the intended audience or issuer.

with jose I would do

decoded = jwt.decode(token, public_key, algorithms=[alg], audience=aud, issuer=issuer)

unable to send refresh and access tokens together in same authentication route

I'm using:

fastapi              0.108.0
fastapi-jwt          0.2.0
python-jose          3.3.0

on Mac OS, python 3.10.13. I'm not able to get the refresh_token cookie set... using:

@router.post("/users/login", status_code=status.HTTP_200_OK)
def login(
        user: UserLogin,
        response: Response,
        session: Session = Depends(get_db)
):
    rec = UserService(session).authenticate_user(user=user)
    if not rec:
        raise HTTPException(status_code=404, detail="User does NOT exist in the system")
    rec = jsonable_encoder(rec)
    subject = {
        'username': rec.get('username'),
        'role': rec.get('role'),
        'departments': rec.get('departments')
    }

    access_token = access_security.create_access_token(subject=subject, expires_delta=timedelta(minutes=1))
    refresh_token = refresh_security.create_refresh_token(subject=subject, expires_delta=timedelta(minutes=2))

    access_security.set_access_cookie(response=response, access_token=access_token)
    refresh_security.set_refresh_cookie(response=response, refresh_token=refresh_token)

    return {'user': rec, 'access_token': access_token, 'refresh_token': refresh_token}

Both show up in the JSON response, but ONLY access_token_cookie cookie is set. If i switch the order of the set_*_cookie() calls, the refresh_token_cookie is set but not access_token_cookie.

I've seen it work, but can't fig. out how or why it's failing to send both now. I'm attempting to use the JwtRefreshBearerCookie.

missing `py.typed` in packaged releases

Hi.
I'm using your library, and I have found that mypy says

Skipping analyzing "fastapi_jwt": module is installed, but missing library stubs or py.typed marker

In your repository I see that you have a py.typed resource, but it seems it's missing in the published package on pypi (I'm using version 0.2.0 and a ls .venv/lib/python3.12/site-packages/fastapi_jwt yelds just __init__.py, __pycache__, and jwt.py)

As your package is typed and you added the marker, can you update the building tools configuration to embed it?

CSRF protect?

There is no CSRF protect here, will this be implemented in the future?

No access token type checking?

"credentials: JwtAuthorizationCredentials = Security(refresh_security)" allows only the refresh token.
"credentials: JwtAuthorizationCredentials = Security(access_security)" allows both the access token and the refresh token.
did you intend this?

class JwtAccess(JwtAuthBase):

def __init__(
    self,
    secret_key: str,
    places: Optional[Set[str]] = None,
    auto_error: bool = True,
    algorithm: str = jwt.ALGORITHMS.HS256,
    access_expires_delta: Optional[timedelta] = None,
    refresh_expires_delta: Optional[timedelta] = None,
):
    super().__init__(
        secret_key,
        places=places,
        auto_error=auto_error,
        algorithm=algorithm,
        access_expires_delta=access_expires_delta,
        refresh_expires_delta=refresh_expires_delta,
    )

async def _get_credentials(
    self,
    bearer: Optional[JwtAuthBase.JwtAccessBearer],
    cookie: Optional[JwtAuthBase.JwtAccessCookie],
) -> Optional[JwtAuthorizationCredentials]:
    payload = await self._get_payload(bearer, cookie)

    if payload:
        return JwtAuthorizationCredentials(
            payload["subject"], payload.get("jti", None)
        )
    return None

class JwtRefresh(JwtAuthBase):

def __init__(
    self,
    secret_key: str,
    places: Optional[Set[str]] = None,
    auto_error: bool = True,
    algorithm: str = jwt.ALGORITHMS.HS256,
    access_expires_delta: Optional[timedelta] = None,
    refresh_expires_delta: Optional[timedelta] = None,
):
    super().__init__(
        secret_key,
        places=places,
        auto_error=auto_error,
        algorithm=algorithm,
        access_expires_delta=access_expires_delta,
        refresh_expires_delta=refresh_expires_delta,
    )

async def _get_credentials(
    self,
    bearer: Optional[JwtAuthBase.JwtRefreshBearer],
    cookie: Optional[JwtAuthBase.JwtRefreshCookie],
) -> Optional[JwtAuthorizationCredentials]:
    payload = await self._get_payload(bearer, cookie)

    if payload is None:
        return None

    if "type" not in payload or payload["type"] != "refresh":
        if self.auto_error:
            raise HTTPException(
                status_code=HTTP_401_UNAUTHORIZED,
                detail="Wrong token: 'type' is not 'refresh'",
            )
        else:
            return None

    return JwtAuthorizationCredentials(
        payload["subject"], payload.get("jti", None)
    )

fastapi-jwt should have other jwt backends besides python-jose. Authlib seems a good candidate.

Hello @k4black,

First, I would like to thank you for your project. I sincerely believe that this project should be merged into the main branch of fastapi.

Now, I think fastapi-jwt should either deprecate python-jose and/or offer an alternative.
python-jose did not received a new release since 2021, and the last commit was 10 month ago. A lot of people are worried about the safety of this repo now:

I think fastapi-jwt offers a lot, I don't want to manually code a jwt handler everytime I start a new project with fastapi like the doc of fastapi suggest. So I would suggest to create a JWT Backend mechanism to support at least authlib (which is heavily maintained). I think PyJWT could be a third option. fastapi-jwt should be generic enough to have custom JWT implementation defined by the user if necessary.

I have a PR coming, but I wanted to create an issue first to explain why I think this feature is mandatory.

Kind regards,

Possible to disable JWT authorization for testing?

Hey,

I am using your excellent library to add JWT based authorization to my FastAPI app. But now I am at a point where I would like to add unit test to my project to check my routes. And for this I would like to disable authorization.

Based on my research this should be doable with app.dependency_overrides , see https://fastapi.tiangolo.com/advanced/testing-dependencies/.

But because we are not actually passing a method to Security I am not sure what to override. I tried passing the same Depends(get_access_security()) code with which I created the dependency annotation into the override, but this does not work.
Therefore I wanted to ask what exactly I should override or if there is another option to disable authorization for my testing purposes.
Below are the relevant snippets from my source code.

config.py

@lru_cache
def get_access_security() -> JwtAccessBearerCookie:
    """Return an JWT access security object to generate and test access tokens.

    Returns:
        JwtAccessBearerCookie: The access security.
    """
    return JwtAccessBearerCookie(
        secret_key=settings.secret_key,
        auto_error=True,
        access_expires_delta=settings.access_expires_delta,
    )

AccessSecurityDependency = Annotated[
    JwtAuthorizationCredentials,
    Depends(get_access_security()),
]

route

 @router.patch(
        "/api/calibration-order/id/{id}",
        response_model=CalibrationOrder,
        response_model_exclude_unset=True,
    )
    async def update_calibration_order_by_id(
        id: str,
        patch: list[dict],
        credentials: AccessSecurityDependency,
    ) -> CalibrationOrder:

py test fixture

@pytest.fixture()
def client_authenticated() -> Generator[TestClient, Any, None]:
    """
    Pytest fixture that yields an instance of TestClient which skips the authentication.

    Yields:
        Generator[TestClient, Any, None]: An instance of the TestClient.
    """

    def get_access_security_override() -> None:
        return None

    app.dependency_overrides[
        Depends(get_access_security())
    ] = get_access_security_override
    with TestClient(app) as c:
        yield c

Is this project actively maintained?

I am looking for a fast api jwt extension that is still maintained. Looks like this repo was created to replace poorly maintained fastapi-jwt-auth but you have PRs opened for 3 months...

How to refresh tokens?

I'm currently trying to implement the refresh token functionality, but I always get the error:

Credentials are not provided

The request is made using axios with withCredentials: true enabled in the options.

Here's the code for the server:

@router.post(
    "/refresh",
)
async def refresh_token(
    response: Response,
    credentials: JwtAuthorizationCredentials = Security(refresh_security),
    db: Session = Depends(get_db),
):
    logger.info("Request: Refresh -> New Request to refresh JWT token.")

    user = get_user_by_id(db, credentials["id"])

    logger.info("Request: Refresh -> Returning new credentials.")

    set_authentication_cookies(response, user)

    return {
        "user": user,
        "detail": "Token refreshed successfully!"
    }

credentials: JwtAuthorizationCredentials = Security(access_security) ): It also allows refresh_ Security access

def get_current_user(
credentials: JwtAuthorizationCredentials = Security(access_security)
)

if not credentials:
    raise HTTPException(status_code=401, detail='error')


return credentials.subject

jwt.md

# 使用python-jose来生成jwt,验证jwt,获取当前用户的方法

# 生成token
# def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
import os
from datetime import datetime, timedelta

from fastapi_jwt import JwtRefreshBearer, JwtAuthorizationCredentials, JwtAccessBearer

from fastapi import Security, HTTPException
from dotenv import load_dotenv

load_dotenv()
secret_key = os.getenv("SECRET_KEY", 'leees')

access_token_expires = int(os.getenv("JWT_EXPIRE_TIME", 7))
refresh_token_expires = int(os.getenv("JWT_REFRESH_TIME", 30))


access_security = JwtAccessBearer(
    secret_key=secret_key,
    auto_error=True,
    # change access token validation timedelta
    access_expires_delta=timedelta(days=access_token_expires)
)


# Read refresh token from bearer header only
refresh_security = JwtRefreshBearer(
    secret_key=secret_key,
    auto_error=True,  # automatically raise HTTPException: HTTP_401_UNAUTHORIZED
    refresh_expires_delta=timedelta(days=refresh_token_expires)
)


def create_token(data: dict):
    return access_security.create_access_token(subject=data)


def create_refresh_token(data: dict):
    return refresh_security.create_refresh_token(subject=data)

# 创建同时返回access_token和refresh_token的方法


def create_tokens_refresh(data: dict):
    access_token = access_security.create_access_token(subject=data)
    refresh_token = refresh_security.create_refresh_token(subject=data)
    return {"access_token": access_token, "refresh_token": refresh_token}

# 刷新token


def refresh(
        credentials: JwtAuthorizationCredentials = Security(refresh_security)
):
    # Update access/refresh tokens pair
    # We can customize expires_delta when creating
    access_token = access_security.create_access_token(
        subject=credentials.subject)
    refresh_token = refresh_security.create_refresh_token(
        subject=credentials.subject, expires_delta=timedelta(days=2))

    return {"access_token": access_token, "refresh_token": refresh_token}


def get_current_user(
        credentials: JwtAuthorizationCredentials = Security(access_security)
):

    # auto_error=False, fo we should check manually

    if not credentials:
        raise HTTPException(status_code=401, detail='error')

    # now we can access Credentials object
    return credentials.subject

Bump supported python version?

Im unable to install this project in my python 3.10 project, as you have pinned >=3.7,<3.10 in setup.cfg

I think this code will probably run with 3.10

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.