mirror of
https://github.com/fastapi-users/fastapi-users.git
synced 2026-03-13 07:49:55 +08:00
* Revamp authentication to allow multiple backends * Make router generate a login route for each backend * Apply black * Remove unused imports * Complete docstrings * Update documentation * WIP add cookie auth * Complete cookie auth unit tests * Add documentation for cookie auth * Fix cookie backend default name * Don't make cookie return a Response
This commit is contained in:
50
docs/configuration/authentication/cookie.md
Normal file
50
docs/configuration/authentication/cookie.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# Cookie
|
||||
|
||||
Cookies are an easy way to store stateful information into the user browser. Thus, it is more useful for browser-based navigation (e.g. a front-end app making API requests) rather than pure API interaction.
|
||||
|
||||
## Configuration
|
||||
|
||||
```py
|
||||
from fastapi_users.authentication import CookieAuthentication
|
||||
|
||||
SECRET = "SECRET"
|
||||
|
||||
auth_backends = []
|
||||
|
||||
cookie_authentication = CookieAuthentication(secret=SECRET, lifetime_seconds=3600))
|
||||
|
||||
auth_backends.append(cookie_authentication)
|
||||
```
|
||||
|
||||
As you can see, instantiation is quite simple. You just have to define a constant `SECRET` which is used to encode the token and the lifetime of the cookie (in seconds).
|
||||
|
||||
You can optionally define the `cookie_name`. **Defaults to `fastapiusersauth`**.
|
||||
|
||||
You can also optionally define the `name` which will be used to generate its [`/login` route](../../usage/routes.md#post-loginname). **Defaults to `cookie`**.
|
||||
|
||||
```py
|
||||
cookie_authentication = CookieAuthentication(
|
||||
secret=SECRET,
|
||||
lifetime_seconds=3600,
|
||||
name="my-cookie",
|
||||
)
|
||||
```
|
||||
|
||||
!!! tip
|
||||
The value of the cookie is actually a JWT. This authentication backend shares most of its logic with the [JWT](./jwt.md) one.
|
||||
|
||||
## Login
|
||||
|
||||
This method will return a response with a valid `set-cookie` header upon successful login:
|
||||
|
||||
!!! success "`200 OK`"
|
||||
|
||||
> Check documentation about [login route](../../usage/routes.md#post-loginname).
|
||||
|
||||
## Authentication
|
||||
|
||||
This method expects that you provide a valid cookie in the headers.
|
||||
|
||||
## Next steps
|
||||
|
||||
We will now configure the main **FastAPI Users** object that will expose the [API router](../router.md).
|
||||
@@ -2,6 +2,15 @@
|
||||
|
||||
**FastAPI Users** allows you to plug in several authentication methods.
|
||||
|
||||
## How it works?
|
||||
|
||||
You can have **several** authentication methods, e.g. a cookie authentication for browser-based queries and a JWT token authentication for pure API queries.
|
||||
|
||||
When checking authentication, each method is run one after the other. The first method yielding a user wins. If no method yields a user, an `HTTPException` is raised.
|
||||
|
||||
Each defined method will generate a [`/login/{name}`](../../usage/routes.md#post-loginname) route where `name` is defined on the authentication method object.
|
||||
|
||||
## Provided methods
|
||||
|
||||
* [JWT authentication](jwt.md)
|
||||
* [Cookie authentication](cookie.md)
|
||||
|
||||
@@ -9,11 +9,38 @@ from fastapi_users.authentication import JWTAuthentication
|
||||
|
||||
SECRET = "SECRET"
|
||||
|
||||
auth = JWTAuthentication(secret=SECRET, lifetime_seconds=3600)
|
||||
auth_backends = []
|
||||
|
||||
jwt_authentication = JWTAuthentication(secret=SECRET, lifetime_seconds=3600))
|
||||
|
||||
auth_backends.append(jwt_authentication)
|
||||
```
|
||||
|
||||
As you can see, instantiation is quite simple. You just have to define a constant `SECRET` which is used to encode the token and the lifetime of token (in seconds).
|
||||
|
||||
You can also optionally define the `name` which will be used to generate its [`/login` route](../../usage/routes.md#post-loginname). **Defaults to `jwt`**.
|
||||
|
||||
```py
|
||||
jwt_authentication = JWTAuthentication(
|
||||
secret=SECRET,
|
||||
lifetime_seconds=3600,
|
||||
name="my-jwt",
|
||||
)
|
||||
```
|
||||
|
||||
## Login
|
||||
|
||||
This method will return a JWT token upon successful login:
|
||||
|
||||
!!! success "`200 OK`"
|
||||
```json
|
||||
{
|
||||
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiOTIyMWZmYzktNjQwZi00MzcyLTg2ZDMtY2U2NDJjYmE1NjAzIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTcxNTA0MTkzfQ.M10bjOe45I5Ncu_uXvOmVV8QxnL-nZfcH96U90JaocI"
|
||||
}
|
||||
```
|
||||
|
||||
> Check documentation about [login route](../../usage/routes.md#post-loginname).
|
||||
|
||||
## Authentication
|
||||
|
||||
This method expects that you provide a `Bearer` authentication with a valid JWT.
|
||||
|
||||
@@ -7,7 +7,7 @@ We're almost there! The last step is to configure the `FastAPIUsers` object that
|
||||
Configure `FastAPIUsers` object with all the elements we defined before. More precisely:
|
||||
|
||||
* `db`: Database adapter instance.
|
||||
* `auth`: Authentication logic instance.
|
||||
* `auth_backends`: List of authentication backends. See [Authentication](./authentication/index.md).
|
||||
* `user_model`: Pydantic model of a user.
|
||||
* `reset_password_token_secret`: Secret to encode reset password token.
|
||||
* `reset_password_token_lifetime_seconds`: Lifetime of reset password token in seconds. Default to one hour.
|
||||
@@ -17,7 +17,7 @@ from fastapi_users import FastAPIUsers
|
||||
|
||||
fastapi_users = FastAPIUsers(
|
||||
user_db,
|
||||
auth,
|
||||
auth_backends,
|
||||
User,
|
||||
SECRET,
|
||||
)
|
||||
|
||||
@@ -20,10 +20,12 @@ class User(BaseUser):
|
||||
pass
|
||||
|
||||
|
||||
auth = JWTAuthentication(secret=SECRET, lifetime_seconds=3600)
|
||||
auth_backends = [
|
||||
JWTAuthentication(secret=SECRET, lifetime_seconds=3600),
|
||||
]
|
||||
|
||||
app = FastAPI()
|
||||
fastapi_users = FastAPIUsers(user_db, auth, User, SECRET)
|
||||
fastapi_users = FastAPIUsers(user_db, auth_backends, User, SECRET)
|
||||
app.include_router(fastapi_users.router, prefix="/users", tags=["users"])
|
||||
|
||||
|
||||
|
||||
@@ -33,10 +33,12 @@ class User(BaseUser):
|
||||
pass
|
||||
|
||||
|
||||
auth = JWTAuthentication(secret=SECRET, lifetime_seconds=3600)
|
||||
auth_backends = [
|
||||
JWTAuthentication(secret=SECRET, lifetime_seconds=3600),
|
||||
]
|
||||
|
||||
app = FastAPI()
|
||||
fastapi_users = FastAPIUsers(user_db, auth, User, SECRET)
|
||||
fastapi_users = FastAPIUsers(user_db, auth_backends, User, SECRET)
|
||||
app.include_router(fastapi_users.router, prefix="/users", tags=["users"])
|
||||
|
||||
|
||||
|
||||
@@ -37,22 +37,15 @@ Register a new user. Will call the `on_after_register` [event handlers](../confi
|
||||
}
|
||||
```
|
||||
|
||||
### `POST /login`
|
||||
### `POST /login/{name}`
|
||||
|
||||
Login a user.
|
||||
Login a user against the method named `name`. Check the corresponding [authentication method](../configuration/authentication/index.md) to view the success response.
|
||||
|
||||
!!! abstract "Payload (`application/x-www-form-urlencoded`)"
|
||||
```
|
||||
username=king.arthur@camelot.bt&password=guinevere
|
||||
```
|
||||
|
||||
!!! success "`200 OK`"
|
||||
```json
|
||||
{
|
||||
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiOTIyMWZmYzktNjQwZi00MzcyLTg2ZDMtY2U2NDJjYmE1NjAzIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTcxNTA0MTkzfQ.M10bjOe45I5Ncu_uXvOmVV8QxnL-nZfcH96U90JaocI"
|
||||
}
|
||||
```
|
||||
|
||||
!!! fail "`422 Validation Error`"
|
||||
|
||||
!!! fail "`400 Bad Request`"
|
||||
|
||||
Reference in New Issue
Block a user