A library for quickly creating authentication using JWT and Cookies. Or storing a JWT token in a session
Project description
FastAPI EasyAuth
What is this?
This library quickly and easily creates authentication using JWT and Cookies. You can also use easyauth to identify an active user
Communication with me
If you want to point out inaccuracies, suggest an idea, or report an error, write to the mail tragglesocial@gmail.com
Using
This is the option where you store the jwt token in cookies. There is a more convenient way to store it in a session. Use the storage option in the session The section about storing jwt in a session is called sessionauth
First, we need to import the EasyAuth and Jwt classes from easyauth
from fastapi_easyauth import EasyAuth, Jwt, ALGORITHM
After that, we create instances of classes
jwt = Jwt(
secret = "SECRET", # The secret key for generating tokens and decoding them. Keep the token secret
algorithm = ALGORITHM.HS256 # The encryption algorithm
model = MyModel # Your Pydantic model. When decoding the token, the result will be converted to this model
)
auth = EasyAuth(
cookie_name = "user" # The Name Of The Cookie File
jwt = jwt
expires = exp.EXPIRES_30_DAYS # Cookie lifetime
)
Great, everything is ready. Now we can create tokens and decode them. Also check if the user is active.
from fastapi import FastAPI, Request, Response, Depends
from fastapi_easyauth import EasyAuth, Jwt, ALGORITHM, exp
from pydantic import BaseModel
class User(BaseModel):
name: str
password: str
app = FastAPI()
jwt = Jwt(
secret = "SECRET",
algorithm = ALGORITHM.HS256
)
auth = EasyAuth(
cookie_name = "user"
jwt = jwt
expires = exp.EXPIRES_30_DAYS
)
@app.post('/log')
def log(user: User, response: Response):
token = jwt.create_token(user)
auth.save_token_in_cookie(response, token)
return {'status': 200}
@app.get('/active')
def active(user: User = Depends(auth.active_user))
return user
sessionauth
Storing a JWT token in a session
This is a new way to store jwt tokens. The token will now be stored in the session. For convenience, the SessionAuth class was created
Before you start working with Session Auth in Fastape, you need to connect SessionMiddleware
from fastapi import FastAPI
from starlette.middleware.sessions import SessionMiddleware
app = FastAPI()
app.add_middleware(SessionMiddleware, secret_key = 'secret-key')
Using
First, we need to import the necessary classes.
from fastapi_easyauth.sessionauth import SessionAuth
from fastapi_easyauth import Jwt
After that, we create instances of the Jwt and SessionAuth classes
jwt = Jwt(
'secret'
)
sessionauth = SessionAuth(
jwt = jwt,
name_in_session = 'session-auth' # our token will be stored under this name in the session
)
To create and save a token, you can use one or two functions
from pydantic import BaseModel
class UserModel(BaseModel):
id: int
username: str
router = APIRouter()
@router.get('/login')
async def login(usermodel: UserModel, request: Request):
token = sessionauth.create_token(subject = usermodel)
sessionauth.save_token_in_session(token, request)
#or
sessionauth.create_and_save_token_in_session(
subject = usermodel,
request = request
)
@router.get('/active')
async def active(
active_user: UserModel = Depends(sessionauth.active_user)
):
return active_user
The active_user
function will return the active user. It will automatically decrypt the token and return the dictionary or Pydantic model. If there is no token, it returns False
Checking if there is an authorized user
Sometimes we want to prevent unauthorized users from accessing our resources. The only_auth
and async_only_auth
decorators were created for this purpose. You must specify request: Request
How it works
We just need to wrap our endpoint in our decorator.
@router.get('/something')
@only_auth
def something(request: Request): ...
@router.get('/something/async')
@async_only_auth
async def something_async(request: Request): ...
You must specify request: Request
only_auth
for synchronous endpoint, and async_only_auth
for asynchronous endpoint
Creating your own decorators
The OnlyAuthCreater
class will help you to create your own decorators
First, we need to create an instance of the OnlyAuthCreater
class.
json_response = JSONResponse(
content = {
'detail': 'Access is closed to unauthorized users'
},
status_code = 401
)
creater = OnlyAuthCreater(
redirect_url = 'http:127.0.0.1:8000/auth/login', # the user will be redirected to this url if he is not logged in.
response = json_response, # this response will be returned if the user is not logged in
sessionauth = sessionauth # an instance of the SessionAuth class
)
only_auth_decorator_redirect = creater.create_only_auth_decorator() # Creating a decorator that will redirect the user to a specific url (which you specified when initializing the OnlyAuthCreater class)
only_auth_decorator_response = creater.create_only_auth_decorator(response = True) # Creating a decorator that will return a JSON response (we specified this response when initializing the OnlyAuthCreater class)
async_only_auth_decorator_redirect = creater.create_async_only_auth_decorator() # Asynchronous version. Redirect to a specific url
async_only_auth_decorator_response = creater.create_async_only_auth_decorator(response = True) # Asynchronous version. Returns a JSON response
Now the decorators you have created can be used
@router.get('/test')
@only_auth_decorator_redirect
def test(request: Request): ...
@router.get('/test')
@only_auth_decorator_response
def test(request: Request): ...
@router.get('/test')
@async_only_auth_decorator_redirect
async def test(request: Request): ...
@router.get('/test')
@async_only_auth_decorator_response
async def test(request: Request): ...
What is the RequestNotAdded error?
This error appears for one simple reason. For the only_auth
, async_auth
and OnlyAuthCreater
decorators to work, you need a request sent to your endpoint. To solve this problem, you need to add the request: Request
function to your endpoint parameters. This is the only way to work for decorators.
Exemple:
# Wrong! You need to specify in the endpoint request
@router.get('/something/async')
@async_only_auth
async def something_async(): ...
# Wrong. This is not the correct name for Request. Be sure to specify the name of the request
@router.get('/something/async')
@async_only_auth
async def something_async(req: Request): ...
# Success!
@router.get('/something/async')
@async_only_auth
async def something_async(request: Request): ...
What was added and changed in version 0.1.0
- Now, using only an instance of the EasyAuth class, you can create a token and immediately save it in a cookie.
@app.post('/login')
def login(user: User, response: Response):
token = auth.create_token(subject = user, response = response)
return token
@app.get('/getToken')
def get_token(request: Request):
data = auth.decode_token(request)
return data
- The name of the Auth class has also been changed to EasyAuth.
- All functions have been documented
- Now, when initializing the Jwt class, you can specify the model. Each time you decode the token, the result will be returned in the form of the model that you specified
class User(BaseModel):
id: int
username: str
jwt = Jwt(
secret = "SECRET",
model = User
)
def get_user(token: str) -> User:
# if you did not specify the model during initialization, the result will be returned as a dictionary
user = jwt.decode_token(token)
return user
def get_user_in_model(token: str) -> User:
# If you are not going to add models when initializing the Jwt class, then you can use the decode_taken_in_model function.
# It accepts a token and a model in which
user = jwt.decode_token_in_model(token, User)
return user
There are also two simple functions in this library so far. The first is password hashing. The second is an error about an unauthorized user.
def hash_password(password: str) -> str:
"""
hash_password: hashes the password
Args:
password (str): User password
Returns:
str: hashed password
"""
return hashlib.sha256(password.encode()).hexdigest()
def not_authorized() -> HTTPException:
"""
not_authorized: a function that returns an error when an unauthorized user
"""
return HTTPException(
status_code=401,
detail='Unauthorized'
)
What was added or changed in version 0.2.1
- A new way of storing the Jwt token has been added. It can now be stored in a session. The SessionAuth class has been added to work with sessions
- Added new decorators
only_auth
andasync_only_auth
. The goal is to return a JSON response if the user is not logged in, otherwise endpoint works - The
OnlyAuthCreater
class has been added. This class creates custom decorators. You can decide which JSON response will be returned to the unauthorized user. Or redirect the user to another link
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file fastapi-easyauth-0.3.0.tar.gz
.
File metadata
- Download URL: fastapi-easyauth-0.3.0.tar.gz
- Upload date:
- Size: 13.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.0.0 CPython/3.11.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | f7149a9cb073be5dec3b050c0cdafb320ecdd5a9cb8cf9ba1ad3859cbfb4a116 |
|
MD5 | 334c1f627f44224e83acf23736e1c511 |
|
BLAKE2b-256 | 82952d30bbb2ebad10c217ffa6cbe59e31083bf170f8d2d61198d2377715ac21 |
File details
Details for the file fastapi_easyauth-0.3.0-py3-none-any.whl
.
File metadata
- Download URL: fastapi_easyauth-0.3.0-py3-none-any.whl
- Upload date:
- Size: 13.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.0.0 CPython/3.11.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | d51006681e49964bae3d2cc5af5199f2c88b524f53d7dbf12152f4d016f8c7ff |
|
MD5 | 99488d050efad6c6c61555c66a01458e |
|
BLAKE2b-256 | c5249bb1d43bbf14de7a634b29fe997e35aec49e17850c084b0dfbd0942782fd |