]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
:memo: Add Security tutorial: Get current user
authorSebastián Ramírez <tiangolo@gmail.com>
Mon, 24 Dec 2018 04:03:59 +0000 (08:03 +0400)
committerSebastián Ramírez <tiangolo@gmail.com>
Mon, 24 Dec 2018 04:03:59 +0000 (08:03 +0400)
docs/tutorial/security/get-current-user.md [new file with mode: 0644]
mkdocs.yml

diff --git a/docs/tutorial/security/get-current-user.md b/docs/tutorial/security/get-current-user.md
new file mode 100644 (file)
index 0000000..88099fb
--- /dev/null
@@ -0,0 +1,120 @@
+In the previous chapter the security system (which is based on the dependency injection system) was giving the path operation function a `token` as a `str`:
+
+```Python hl_lines="10"
+{!./src/security/tutorial001.py!}
+```
+
+But that is still not that useful.
+
+Let's make it give us the current user.
+
+## Create a user model
+
+First, let's create a Pydantic user model.
+
+The same way we use Pydantic to declare bodies, we can use it anywhere else:
+
+```Python hl_lines="5 12 13 14 15 16"
+{!./src/security/tutorial002.py!}
+```
+
+## Create a `get_current_user` dependency
+
+Let's create a dependency `get_current_user`.
+
+Remember that dependencies can have sub-dependencies?
+
+And remember that `Security` is based on `Depends`?
+
+So, we can have sub-dependencies using `Security` too.
+
+`get_current_user` will have a `Security` dependency with the same `oauth2_scheme` we created before.
+
+The same as we were doing before in the path operation direclty, our new dependency will receive a `token` as a `str` from the `Security` dependency:
+
+```Python hl_lines="25"
+{!./src/security/tutorial002.py!}
+```
+
+## Get the user
+
+`get_current_user` will use a (fake) utility function we created, that takes a token as a `str` and returns our Pydantic `User` model:
+
+```Python hl_lines="19 20 21 22 26 27"
+{!./src/security/tutorial002.py!}
+```
+
+## Inject the current user
+
+So now we can use the same `Depends` with our `get_current_user` in the path operation:
+
+```Python hl_lines="31"
+{!./src/security/tutorial002.py!}
+```
+
+!!! info
+    Here you could actually use `Security` instead of depends too.
+    
+    But it is not required.
+
+    The key point where you should use `Security` is when passing an instance of `OAuth2PasswordBearer`.
+
+    Because **FastAPI** will use the fact that you are using `Security` and that you are passing an instance of that class `OAuth2PasswordBearer` (that inherits from `SecurityBase`) to create all the security definitions in OpenAPI.
+
+Notice that we declare the type of `current_user` as the Pydantic model `User`.
+
+This will help us inside of the function with all the completion and type checks.
+
+!!! tip
+    You might remember that request bodies are also declared with Pydantic models.
+
+    Here **FastAPI** won't get confused because you are using `Depends` or `Security`.
+
+!!! check
+    The way this dependency system is designed allows us to have different dependencies (different "dependables") that all return a `User` model.
+
+    We are not restricted to having only one dependency that can return that type of data.
+
+
+## Other models
+
+You can now get the current user directly in the path operation functions and deal with the security mechanisms at the **Dependency Injection** level, using `Security`.
+
+And you can use any model or data for the security requirements (in this case, a Pydantic model `User`).
+
+But you are not restricted to using some specific data model, class or type.
+
+Do you want to have an `id` and `email` and not have any `username` in your model? Sure. You can use these same tools.
+
+Do you want to just have a `str`? Or just a `dict`? Or a database class model instance directly? It all works the same way.
+
+
+## Code size
+
+This example might seem verbose. Have in mind that we are mixing security, data models utility functions and path operations in the same file.
+
+But here's the key point.
+
+The security and dependency injection stuff is written once.
+
+And you can make it as complex as you want. And still, have it written only once, in a single place.
+
+But you can have thousands of endpoints (path operations) using the same security system.
+
+And all of them (or any portion of them that you want) can take the advantage of re-using these dependencies or any other dependencies you create.
+
+And all these thousands of path operations can be as small as 3 lines:
+
+```Python hl_lines="30 31 32"
+{!./src/security/tutorial002.py!}
+```
+
+## Recap
+
+You can now get the current user directly in your path operation function.
+
+We are already halfway there.
+
+We just need to add a path operation for the user / client to actually send the `username` and `password`.
+
+That comes next.
\ No newline at end of file
index 6dc5e9926659ed12eed3c3192e08caca0f7f5459..8f9bab9e0d758b98ef51ce3cdbd52d2429fa3bdf 100644 (file)
@@ -48,6 +48,7 @@ nav:
         - Security: 
             - Security Intro: 'tutorial/security/intro.md'
             - First Steps: 'tutorial/security/first-steps.md'
+            - Get Current User: 'tutorial/security/get-current-user.md'
             - Simple OAuth2 with Password and Bearer: 'tutorial/security/simple-oauth2.md'
             - OAuth2 with Password (and hashing), Bearer with JWT tokens: 'tutorial/security/oauth2-jwt.md'
         - SQL (Relational) Databases: 'tutorial/sql-databases.md'