sanic/guide/content/en/guide/how-to/authentication.md
2023-09-06 15:44:00 +03:00

118 lines
3.0 KiB
Markdown

# Authentication
> How do I control authentication and authorization?
This is an _extremely_ complicated subject to cram into a few snippets. But, this should provide you with an idea on ways to tackle this problem. This example uses [JWTs](https://jwt.io/), but the concepts should be equally applicable to sessions or some other scheme.
## `server.py`
```python
from sanic import Sanic, text
from auth import protected
from login import login
app = Sanic("AuthApp")
app.config.SECRET = "KEEP_IT_SECRET_KEEP_IT_SAFE"
app.blueprint(login)
@app.get("/secret")
@protected
async def secret(request):
return text("To go fast, you must be fast.")
```
## `login.py`
```python
import jwt
from sanic import Blueprint, text
login = Blueprint("login", url_prefix="/login")
@login.post("/")
async def do_login(request):
token = jwt.encode({}, request.app.config.SECRET)
return text(token)
```
## `auth.py`
```python
from functools import wraps
import jwt
from sanic import text
def check_token(request):
if not request.token:
return False
try:
jwt.decode(
request.token, request.app.config.SECRET, algorithms=["HS256"]
)
except jwt.exceptions.InvalidTokenError:
return False
else:
return True
def protected(wrapped):
def decorator(f):
@wraps(f)
async def decorated_function(request, *args, **kwargs):
is_authenticated = check_token(request)
if is_authenticated:
response = await f(request, *args, **kwargs)
return response
else:
return text("You are unauthorized.", 401)
return decorated_function
return decorator(wrapped)
```
This decorator pattern is taken from the [decorators page](/en/guide/best-practices/decorators.md).
---
```bash
$ curl localhost:9999/secret -i
HTTP/1.1 401 Unauthorized
content-length: 21
connection: keep-alive
content-type: text/plain; charset=utf-8
You are unauthorized.
$ curl localhost:9999/login -X POST
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.e30.rjxS7ztIGt5tpiRWS8BGLUqjQFca4QOetHcZTi061DE
$ curl localhost:9999/secret -i -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.e30.rjxS7ztIGt5tpiRWS8BGLUqjQFca4QOetHcZTi061DE"
HTTP/1.1 200 OK
content-length: 29
connection: keep-alive
content-type: text/plain; charset=utf-8
To go fast, you must be fast.
$ curl localhost:9999/secret -i -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.e30.BAD"
HTTP/1.1 401 Unauthorized
content-length: 21
connection: keep-alive
content-type: text/plain; charset=utf-8
You are unauthorized.
```
Also, checkout some resources from the community:
- Awesome Sanic - [Authorization](https://github.com/mekicha/awesome-sanic/blob/master/README.md#authentication) & [Session](https://github.com/mekicha/awesome-sanic/blob/master/README.md#session)
- [EuroPython 2020 - Overcoming access control in web APIs](https://www.youtube.com/watch?v=Uqgoj43ky6A)