aliev / aioauth

Asynchronous OAuth 2.0 provider for Python 3

Home Page:https://aliev.me/aioauth

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Questions about the combination of this library and AuthenticationMiddleware

hidaris opened this issue · comments

  • aioauth version: 0.1.4
  • Python version: 3.8.6
  • Operating System: manjaro 20.2

Description

I tried the example in the readme, but it's not quite clear how to combine it with AuthenticationMiddleware

What I Did

Add some persistent models to the examples in the readme
commented

I think it doesn't depend on your OS
@hidaris

What error did you get?

commented

@aliev how about removing OS from the issue template?

Hi, @hidaris. To access the request.user object fastapi as well as starlette requires the AuthenticationMiddleware.

Here is an example of how you can connect AuthenticationMiddleware to fastapi (JWT example):

from fastapi import FastAPI
from starlette.middleware.authentication import AuthenticationMiddleware
from starlette.authentication import (
    AuthCredentials,
    AuthenticationBackend,
    SimpleUser,
    UnauthenticatedUser,
)

class BasicAuthBackend(AuthenticationBackend):
    async def authenticate(self, request):
        # Get JWT token from user's cookies
        token = request.cookies.get("token")

        # Returns UnauthenticatedUser if token does not exists in cookies
        if not token:
            return AuthCredentials(), UnauthenticatedUser()

        # Checks the validity of the JWT token, if token is invalid returns UnauthenticatedUser object
        try:
            jwt_decoded = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
        except JWTError:
            return AuthCredentials(), UnauthenticatedUser()

        # In case if token is valid returns an object of the authorized user
        return AuthCredentials(["authenticated"]), SimpleUser(jwt_decoded["email"])

...
app = FastAPI()
app.add_middleware(AuthenticationMiddleware, backend=BasicAuthBackend())
...

Now in your views you can check whether the user is authorized or not:

...
user = None
if request.user.is_authenticated:
    user = request.user

return OAuth2Request(
    settings=settings,
    method=RequestMethod[method],
    headers=headers,
    post=Post(**post),
    query=Query(**query_params),
    url=url,
    user=user,
)

I would also recommend the fastapi-users project, which implements the user registration and authentication system for fastapi.

I also want to note that for aioauth.requests.Request the user argument is optional, if the user object is None, aioauth will consider that the user is not authorized.

Thanks for the detailed explanation!