fastapi-easyauth


Namefastapi-easyauth JSON
Version 0.3.3 PyPI version JSON
download
home_pagehttps://github.com/GwenB1ade/fastapi-easyauth
SummaryA library for quickly creating authentication using JWT and Cookies. Or storing a JWT token in a session
upload_time2024-07-30 15:40:53
maintainerNone
docs_urlNone
authorduckduck
requires_python>=3.9
licenseNone
keywords fastapi fastapi-jwt fastapi-easyauth fastapi-auth sessioauth sessioauth
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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](#sessionauth)
> 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
```python
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. 
```python
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
```python
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.
```python
from fastapi_easyauth.sessionauth import SessionAuth
from fastapi_easyauth import Jwt
```
After that, we create instances of the Jwt and SessionAuth classes
```python
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
```python
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.
```python
@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.

```python
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
```python
@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:
```python

# 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.

```python
@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

```python
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. ###

```python
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``` and ```async_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

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/GwenB1ade/fastapi-easyauth",
    "name": "fastapi-easyauth",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "fastapi fastapi-jwt fastapi-easyauth fastapi-auth sessioauth SessioAuth",
    "author": "duckduck",
    "author_email": "dimondtp@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/cc/a6/a340125037c0fc6f8c181342ee330091c0ac3b4ce088df685fff7ea44c5b/fastapi-easyauth-0.3.3.tar.gz",
    "platform": null,
    "description": "# FastAPI EasyAuth #\n\n## What is this? ##\nThis library quickly and easily creates authentication using JWT and Cookies. You can also use easyauth to identify an active user\n\n### Communication with me\n__If you want to point out inaccuracies, suggest an idea, or report an error, write to the mail tragglesocial@gmail.com__\n\n### Using ###\n\n> This is the option where you store the jwt token in cookies. There is a more convenient way to store it in a session.\n> [Use the storage option in the session](#sessionauth)\n> The section about storing jwt in a session is called **sessionauth**\n\n\nFirst, we need to import the EasyAuth and Jwt classes from easyauth\n\n    from fastapi_easyauth import EasyAuth, Jwt, ALGORITHM\n\nAfter that, we create instances of classes\n```python\njwt = Jwt(\n    secret = \"SECRET\", # The secret key for generating tokens and decoding them. Keep the token secret\n    algorithm = ALGORITHM.HS256 # The encryption algorithm\n    model = MyModel # Your Pydantic model. When decoding the token, the result will be converted to this model\n)\n\nauth = EasyAuth(\n    cookie_name = \"user\" # The Name Of The Cookie File\n    jwt = jwt\n    expires = exp.EXPIRES_30_DAYS # Cookie lifetime\n    )\n```\n\nGreat, everything is ready. Now we can create tokens and decode them. Also check if the user is active. \n```python\nfrom fastapi import FastAPI, Request, Response, Depends\nfrom fastapi_easyauth import EasyAuth, Jwt, ALGORITHM, exp\n\nfrom pydantic import BaseModel\n\nclass User(BaseModel):\n    name: str\n    password: str\n\napp = FastAPI()\n\njwt = Jwt(\n    secret = \"SECRET\",\n    algorithm = ALGORITHM.HS256\n)\n\nauth = EasyAuth(\n    cookie_name = \"user\"\n    jwt = jwt\n    expires = exp.EXPIRES_30_DAYS\n)\n\n@app.post('/log')\ndef log(user: User, response: Response):\n    token = jwt.create_token(user)\n    auth.save_token_in_cookie(response, token)\n    return {'status': 200}\n\n\n@app.get('/active')\ndef active(user: User = Depends(auth.active_user))\n    return user\n```\n----------\n# sessionauth\n# Storing a JWT token in a session\nThis is a new way to store jwt tokens. The token will now be stored in the session. For convenience, the SessionAuth class was created\n\n### Before you start working with Session Auth in Fastape, you need to connect SessionMiddleware\n```python\nfrom fastapi import FastAPI\nfrom starlette.middleware.sessions import SessionMiddleware\napp = FastAPI()\napp.add_middleware(SessionMiddleware, secret_key = 'secret-key')\n```\n\n# Using\nFirst, we need to import the necessary classes.\n```python\nfrom fastapi_easyauth.sessionauth import SessionAuth\nfrom fastapi_easyauth import Jwt\n```\nAfter that, we create instances of the Jwt and SessionAuth classes\n```python\njwt = Jwt(\n\t'secret'\n)\n\nsessionauth = SessionAuth(\n\tjwt = jwt,\n\tname_in_session = 'session-auth' # our token will be stored under this name in the session\n)\n```\n\nTo create and save a token, you can use one or two functions\n```python\nfrom pydantic import BaseModel\n\nclass UserModel(BaseModel):\n\tid: int\n\tusername: str\n\n\nrouter = APIRouter()\n\n@router.get('/login')\nasync def login(usermodel: UserModel, request: Request):\n\ttoken = sessionauth.create_token(subject = usermodel)\n\tsessionauth.save_token_in_session(token, request)\n\t\n\t#or\n\t\n\tsessionauth.create_and_save_token_in_session(\n\tsubject = usermodel,\n\trequest = request\n)\n\n  \n\n@router.get('/active')\nasync def active(\nactive_user: UserModel = Depends(sessionauth.active_user)\n):\n\n\treturn active_user\n```\nThe ```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\n\n# Checking if there is an authorized user\nSometimes 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```\n## How it works\nWe just need to wrap our endpoint in our decorator.\n```python\n@router.get('/something')\n@only_auth\ndef something(request: Request): ...\n\n\n@router.get('/something/async')\n@async_only_auth\nasync def something_async(request: Request): ...\n```\nYou must specify request: Request\n```only_auth``` for synchronous endpoint, and ```async_only_auth``` for asynchronous endpoint\n\n# Creating your own decorators\nThe ```OnlyAuthCreater``` class will help you to create your own decorators\nFirst, we need to create an instance of the ```OnlyAuthCreater``` class.\n\n```python\njson_response = JSONResponse(\n    content = {\n        'detail': 'Access is closed to unauthorized users'\n    },\n    status_code = 401\n)\n\ncreater = OnlyAuthCreater(\n    redirect_url = 'http:127.0.0.1:8000/auth/login', # the user will be redirected to this url if he is not logged in.\n    response = json_response, # this response will be returned if the user is not logged in\n    sessionauth = sessionauth # an instance of the SessionAuth class\n)\n\nonly_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)\nonly_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)\n\nasync_only_auth_decorator_redirect = creater.create_async_only_auth_decorator() # Asynchronous version. Redirect to a specific url\nasync_only_auth_decorator_response = creater.create_async_only_auth_decorator(response = True) # Asynchronous version. Returns a JSON response\n```\nNow the decorators you have created can be used\n```python\n@router.get('/test')\n@only_auth_decorator_redirect\ndef test(request: Request): ...\n\n@router.get('/test')\n@only_auth_decorator_response\ndef test(request: Request): ...\n\n\n@router.get('/test')\n@async_only_auth_decorator_redirect\nasync def test(request: Request): ...\n\n@router.get('/test')\n@async_only_auth_decorator_response\nasync def test(request: Request): ...\n```\n\n## What is the RequestNotAdded error?\nThis 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.\nExemple:\n```python\n\n# Wrong! You need to specify in the endpoint request\n@router.get('/something/async')\n@async_only_auth\nasync def something_async(): ...\n\n# Wrong. This is not the correct name for Request. Be sure to specify the name of the request\n@router.get('/something/async')\n@async_only_auth\nasync def something_async(req: Request): ...\n\n# Success!\n@router.get('/something/async')\n@async_only_auth\nasync def something_async(request: Request): ...\n```\n---\n\n# What was added and changed in version 0.1.0 #\n\n+ Now, using only an instance of the EasyAuth class, you can create a token and immediately save it in a cookie.\n\n```python\n@app.post('/login')\ndef login(user: User, response: Response):\n    token = auth.create_token(subject = user, response = response)\n    return token\n\n@app.get('/getToken')\ndef get_token(request: Request):\n    data = auth.decode_token(request)\n    return data\n```\n\n+ The name of the Auth class has also been changed to EasyAuth.\n+ All functions have been documented\n+ 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\n\n```python\nclass User(BaseModel):\n    id: int\n    username: str\n\njwt = Jwt(\n    secret = \"SECRET\",\n    model = User\n)\n\n\ndef get_user(token: str) -> User:\n    # if you did not specify the model during initialization, the result will be returned as a dictionary\n    \n    user = jwt.decode_token(token)\n    return user\n\n\ndef get_user_in_model(token: str) -> User:\n    # If you are not going to add models when initializing the Jwt class, then you can use the decode_taken_in_model function.\n    # It accepts a token and a model in which\n    \n    user = jwt.decode_token_in_model(token, User)\n    return user\n```\n\n----------\n### 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. ###\n\n```python\ndef hash_password(password: str) -> str:\n    \"\"\"\n    hash_password: hashes the password\n\n    Args:\n        password (str): User password\n\n    Returns:\n        str: hashed password\n    \"\"\"\n\n    return hashlib.sha256(password.encode()).hexdigest()\n\n\ndef not_authorized() -> HTTPException:\n    \"\"\"\n    not_authorized: a function that returns an error when an unauthorized user\n    \"\"\"\n\n    return HTTPException(\n        status_code=401,\n        detail='Unauthorized'\n    )\n```\n\n### What was added or changed in version 0.2.1\n- 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\n- Added new decorators ```only_auth``` and ```async_only_auth```. The goal is to return a JSON response if the user is not logged in, otherwise endpoint works\n- 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\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A library for quickly creating authentication using JWT and Cookies. Or storing a JWT token in a session",
    "version": "0.3.3",
    "project_urls": {
        "GitHub": "https://github.com/GwenB1ade/fastapi-easyauth",
        "Homepage": "https://github.com/GwenB1ade/fastapi-easyauth"
    },
    "split_keywords": [
        "fastapi",
        "fastapi-jwt",
        "fastapi-easyauth",
        "fastapi-auth",
        "sessioauth",
        "sessioauth"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f4c2b350f257278b0478fcd018f6e2de437a3550139d177f951e4be3d334e633",
                "md5": "81f0bcb0ab66d9e14645ec981ec590c2",
                "sha256": "4b83f4782467dd35752a5a108c85e7a7a2fb4e9924d88663dc930e17f9028489"
            },
            "downloads": -1,
            "filename": "fastapi_easyauth-0.3.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "81f0bcb0ab66d9e14645ec981ec590c2",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 12816,
            "upload_time": "2024-07-30T15:40:51",
            "upload_time_iso_8601": "2024-07-30T15:40:51.580879Z",
            "url": "https://files.pythonhosted.org/packages/f4/c2/b350f257278b0478fcd018f6e2de437a3550139d177f951e4be3d334e633/fastapi_easyauth-0.3.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "cca6a340125037c0fc6f8c181342ee330091c0ac3b4ce088df685fff7ea44c5b",
                "md5": "55fb3dd108b06c9ab8f5ca90365011f1",
                "sha256": "50a5e4fcd549088c402788db63a435cf6c886cf849e0319ec077619196152a8a"
            },
            "downloads": -1,
            "filename": "fastapi-easyauth-0.3.3.tar.gz",
            "has_sig": false,
            "md5_digest": "55fb3dd108b06c9ab8f5ca90365011f1",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 13133,
            "upload_time": "2024-07-30T15:40:53",
            "upload_time_iso_8601": "2024-07-30T15:40:53.163931Z",
            "url": "https://files.pythonhosted.org/packages/cc/a6/a340125037c0fc6f8c181342ee330091c0ac3b4ce088df685fff7ea44c5b/fastapi-easyauth-0.3.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-07-30 15:40:53",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "GwenB1ade",
    "github_project": "fastapi-easyauth",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "fastapi-easyauth"
}
        
Elapsed time: 9.26663s