Revamp authentication routes structure (#201)

* Fix #68: use makefun to generate dynamic dependencies

* Remove every Starlette imports

* Split every routers and remove event handlers

* Make users router optional

* Pass after_update handler to get_users_router

* Update documentation

* Remove test file

* Write migration doc for splitted routers
This commit is contained in:
François Voron
2020-05-24 10:18:01 +02:00
committed by GitHub
parent 0a0dcadfdc
commit 7721f8dcc1
48 changed files with 1633 additions and 1167 deletions

View File

@@ -45,4 +45,4 @@ def protected_route():
return 'Hello, some user.'
```
You can see more about it [in FastAPI docs](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
You can read more about this [in FastAPI docs](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).

View File

@@ -14,12 +14,12 @@ First step, of course, is to register as a user.
-H "Content-Type: application/json" \
-X POST \
-d "{\"email\": \"king.arthur@camelot.bt\",\"password\": \"guinevere\"}" \
http://localhost:8000/users/register
http://localhost:8000/auth/register
```
=== "axios"
```ts
axios.post('http://localhost:8000/users/register', {
axios.post('http://localhost:8000/auth/register', {
email: 'king.arthur@camelot.bt',
password: 'guinevere',
})
@@ -51,7 +51,7 @@ You'll get a JSON response looking like this:
Now, you can login as this new user.
Each [authentication backend](../configuration/authentication/index.md) will produce a single route. For example, the [JWT backend](../configuration/authentication/jwt.md) will produce the `/users/login/jwt` route. Each backend will have a different response.
You can generate a [login route](../configuration/routers/auth.md) for each [authentication backend](../configuration/authentication/index.md). Each backend will have a different response.
### JWT backend
@@ -64,7 +64,7 @@ Each [authentication backend](../configuration/authentication/index.md) will pro
-X POST \
-F "username=king.arthur@camelot.bt" \
-F "password=guinevere" \
http://localhost:8000/users/login/jwt
http://localhost:8000/auth/jwt/login
```
=== "axios"
@@ -73,7 +73,7 @@ Each [authentication backend](../configuration/authentication/index.md) will pro
formData.set('username', 'king.arthur@camelot.bt');
formData.set('password', 'guinevere');
axios.post(
'http://localhost:8000/users/login/jwt',
'http://localhost:8000/auth/jwt/login',
formData,
{
headers: {
@@ -112,7 +112,7 @@ You can use this token to make authenticated requests as the user `king.arthur@c
-X POST \
-F "username=king.arthur@camelot.bt" \
-F "password=guinevere" \
http://localhost:8000/users/login/cookie
http://localhost:8000/auth/cookie/login
```
=== "axios"
@@ -121,7 +121,7 @@ You can use this token to make authenticated requests as the user `king.arthur@c
formData.set('username', 'king.arthur@camelot.bt');
formData.set('password', 'guinevere');
axios.post(
'http://localhost:8000/users/login/cookie',
'http://localhost:8000/auth/cookie/login',
formData,
{
headers: {
@@ -380,12 +380,12 @@ We can also end the session. Note that it doesn't apply to every [authentication
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-X POST \
http://localhost:8000/users/logout/cookie
http://localhost:8000/auth/cookie/logout
```
=== "axios"
```ts
axios.post('http://localhost:8000/users/logout/cookie',
axios.post('http://localhost:8000/auth/cookie/logout',
null,
{
headers: {

View File

@@ -2,11 +2,49 @@
You'll find here the routes exposed by **FastAPI Users**. Note that you can also review them through the [interactive API docs](https://fastapi.tiangolo.com/tutorial/first-steps/#interactive-api-docs).
## Unauthenticated
## Auth router
Each [authentication backend](../configuration/authentication/index.md) you [generate a router for](../configuration/routers/auth.md) will produce the following routes. Take care about the prefix you gave it, especially if you have several backends.
### `POST /login`
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
```
!!! fail "`422 Validation Error`"
!!! fail "`400 Bad Request`"
Bad credentials or the user is inactive.
```json
{
"detail": "LOGIN_BAD_CREDENTIALS"
}
```
### `POST /logout`
Logout the authenticated user against the method named `name`. Check the corresponding [authentication method](../configuration/authentication/index.md) to view the success response.
!!! fail "`401 Unauthorized`"
Missing token or inactive user.
!!! success "`200 OK`"
The logout process was successful.
!!! tip
Some backend (like JWT) won't produce this route.
## Register router
### `POST /register`
Register a new user. Will call the `on_after_register` [event handlers](../configuration/router.md#event-handlers) on successful registration.
Register a new user. Will call the `after_register` [handler](../configuration/routers/register.md#after-register) on successful registration.
!!! abstract "Payload"
```json
@@ -37,42 +75,11 @@ Register a new user. Will call the `on_after_register` [event handlers](../confi
}
```
### `POST /login/{name}`
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
```
!!! fail "`422 Validation Error`"
!!! fail "`400 Bad Request`"
Bad credentials or the user is inactive.
```json
{
"detail": "LOGIN_BAD_CREDENTIALS"
}
```
### `POST /logout/{name}`
Logout the authenticated user against the method named `name`. Check the corresponding [authentication method](../configuration/authentication/index.md) to view the success response.
!!! fail "`401 Unauthorized`"
Missing token or inactive user.
!!! success "`200 OK`"
The logout process was successful.
!!! success "`202 Accepted`"
The logout process is not applicable for this authentication backend (e.g. JWT).
## Reset password router
### `POST /forgot-password`
Request a reset password procedure. Will generate a temporary token and call the `on_after_forgot_password` [event handlers](../configuration/router.md#event-handlers) if the user exists.
Request a reset password procedure. Will generate a temporary token and call the `after_forgot_password` [handlers](../configuration/routers/reset.md#after-forgot-password) if the user exists.
To prevent malicious users from guessing existing users in your databse, the route will always return a `202 Accepted` response, even if the user requested does not exist.
@@ -110,11 +117,11 @@ Reset a password. Requires the token generated by the `/forgot-password` route.
}
```
### OAuth routes
## OAuth router
Each OAuth router you define will expose the two following routes.
#### `GET /authorize`
### `GET /authorize`
Return the authorization URL for the OAuth service where you should redirect your user.
@@ -134,7 +141,7 @@ Return the authorization URL for the OAuth service where you should redirect you
!!! fail "`400 Bad Request`"
Unknown authentication backend.
#### `GET /callback`
### `GET /callback`
Handle the OAuth callback.
@@ -155,7 +162,7 @@ Depending on the situation, several things can happen:
* A new user is created and linked to the OAuth account.
* The user is authenticated following the chosen [authentication method](../configuration/authentication/index.md).
## Authenticated
## Users router
### `GET /me`
@@ -199,8 +206,6 @@ Update the current authenticated active user.
!!! fail "`401 Unauthorized`"
Missing token or inactive user.
## Superuser
### `GET /{user_id}`
Return the user with id `user_id`.