From 1e86080ce051cf041930d260d5da3aefa438a2be Mon Sep 17 00:00:00 2001 From: Roberto Prevato Date: Sun, 19 Oct 2025 21:40:34 +0200 Subject: [PATCH 1/3] Fix error in CookieAuth docs --- blacksheep/docs/authentication.md | 183 +++++------------------------- 1 file changed, 26 insertions(+), 157 deletions(-) diff --git a/blacksheep/docs/authentication.md b/blacksheep/docs/authentication.md index 01c4c66..63f5f01 100644 --- a/blacksheep/docs/authentication.md +++ b/blacksheep/docs/authentication.md @@ -527,174 +527,34 @@ with signed and encrypted user data using `itsdangerous.Serializer`. ### Basic Cookie authentication setup -The following example shows how to configure Cookie authentication: +The following example shows how to use the built-in `CookieAuthentication` class: ```python -from blacksheep import Application, get, json -from blacksheep.server.authentication.cookie import CookieAuthentication -from blacksheep.server.authorization import auth - -app = Application() - -# Configure cookie authentication -app.use_authentication().add( - CookieAuthentication( - cookie_name="user_session", # Default: "identity" - secret_keys=["your-secret-key"], # Keys for signing/encryption - auth_scheme="CookieAuth" # Custom scheme name - ) -) - -app.use_authorization() - - -@auth() -@get("/profile") -async def get_profile(request): - return { - "message": "User profile", - "user": request.user.claims - } - - -@get("/login") -async def login(request): - """Example login endpoint that sets authentication cookie""" - response = json({"message": "Login successful"}) - - # Get the cookie authentication handler - cookie_auth = app.services.resolve(CookieAuthentication) - - # Set user data in cookie (typically done after validating credentials) - user_data = { - "sub": "user123", - "name": "John Doe", - "roles": ["user"], - "exp": 1234567890 # Optional expiration timestamp - } - - cookie_auth.set_cookie(user_data, response, secure=True) - return response - - -@get("/logout") -async def logout(request): - """Example logout endpoint that removes authentication cookie""" - response = json({"message": "Logged out"}) - - # Get the cookie authentication handler - cookie_auth = app.services.resolve(CookieAuthentication) - - # Remove the authentication cookie - cookie_auth.unset_cookie(response) - return response -``` - -### Advanced Cookie configuration - -You can customize the cookie authentication with additional options: - -```python -from blacksheep import Application -from blacksheep.server.authentication.cookie import CookieAuthentication -from itsdangerous import JSONWebSignatureSerializer - -app = Application() - -# Advanced configuration with custom serializer -custom_serializer = JSONWebSignatureSerializer("your-secret-key") - -app.use_authentication().add( - CookieAuthentication( - cookie_name="app_session", - secret_keys=["primary-key", "backup-key"], # Key rotation support - serializer=custom_serializer, # Custom serializer - auth_scheme="CustomCookieAuth" - ) -) -``` - -### Working with cookie data +import secrets +from datetime import datetime, timedelta, UTC -The cookie authentication handler provides methods to manage authentication cookies: - -```python -from blacksheep import Application, get, post, json +from blacksheep import Application, get, json, post from blacksheep.server.authentication.cookie import CookieAuthentication app = Application() +# Secure cookie configuration cookie_auth = CookieAuthentication( - cookie_name="session", - secret_keys=["your-secret-key"] + cookie_name="secure_session", + secret_keys=[ + secrets.token_urlsafe(32), + secrets.token_urlsafe(32), + ], ) - app.use_authentication().add(cookie_auth) -@post("/api/signin") -async def signin(request): - """Sign in endpoint that validates credentials and sets cookie""" - # TODO: Validate user credentials from request body - - response = json({"success": True}) - - # Set authentication cookie with user claims - user_claims = { - "sub": "user123", - "email": "user@example.com", - "roles": ["user", "admin"], - "department": "IT" - } - - cookie_auth.set_cookie(user_claims, response, secure=True) - return response - - -@post("/api/signout") -async def signout(request): - """Sign out endpoint that removes the authentication cookie""" - response = json({"message": "Signed out successfully"}) - cookie_auth.unset_cookie(response) - return response - - -@get("/api/user") -async def get_current_user(request): - """Get current user info from cookie authentication""" - if request.user and request.user.is_authenticated(): - return json({ - "authenticated": True, - "claims": request.user.claims - }) - else: - return json({"authenticated": False}) -``` - -### Cookie security considerations - -When using cookie authentication, consider these security practices: - -```python -from blacksheep import Application -from blacksheep.server.authentication.cookie import CookieAuthentication -from datetime import datetime, timedelta - -app = Application() - -# Secure cookie configuration -app.use_authentication().add( - CookieAuthentication( - cookie_name="secure_session", - secret_keys=[ - "primary-secret-key-256-bits-long", - "backup-secret-key-for-rotation" - ] - ) -) +@get("/") +async def home(request) -> dict: + return request.user.claims -@app.route("/login", methods=["POST"]) +@post("/login") async def secure_login(request): # TODO: Validate credentials @@ -704,16 +564,25 @@ async def secure_login(request): user_data = { "sub": "user123", "name": "John Doe", - "exp": int((datetime.utcnow() + timedelta(hours=24)).timestamp()) + "exp": int((datetime.now(UTC) + timedelta(hours=24)).timestamp()), } - cookie_auth = app.services.resolve(CookieAuthentication) cookie_auth.set_cookie( user_data, response, - secure=True # Always use secure=True in production with HTTPS + secure=True, # Always use secure=True in production with HTTPS ) return response + + +@get("/logout") +async def logout(request): + """Example logout endpoint that removes authentication cookie""" + response = json({"message": "Logged out"}) + + # Remove the authentication cookie + cookie_auth.unset_cookie(response) + return response ``` /// admonition | Security recommendations From 5a4b0ebb7d27551a79c90e3eaba31b49fed93385 Mon Sep 17 00:00:00 2001 From: Roberto Prevato Date: Sun, 19 Oct 2025 21:49:31 +0200 Subject: [PATCH 2/3] Update authentication.md --- blacksheep/docs/authentication.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/blacksheep/docs/authentication.md b/blacksheep/docs/authentication.md index 63f5f01..54b7bbb 100644 --- a/blacksheep/docs/authentication.md +++ b/blacksheep/docs/authentication.md @@ -529,6 +529,11 @@ with signed and encrypted user data using `itsdangerous.Serializer`. The following example shows how to use the built-in `CookieAuthentication` class: +**Summary:** +- `set_cookie` is used to securely set an authentication cookie containing user claims and expiration, typically after a successful login. +- `unset_cookie` removes the authentication cookie, logging the user out. +- `request.user.claims` allows you to access the authenticated user's claims in request handlers, such as user ID, name, or roles. + ```python import secrets from datetime import datetime, timedelta, UTC From 5162a083f0f6ad0cadddad157d0ce95ecc0c4b16 Mon Sep 17 00:00:00 2001 From: Roberto Prevato Date: Sun, 19 Oct 2025 21:54:47 +0200 Subject: [PATCH 3/3] Update authentication.md --- blacksheep/docs/authentication.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/blacksheep/docs/authentication.md b/blacksheep/docs/authentication.md index 54b7bbb..fb32ec1 100644 --- a/blacksheep/docs/authentication.md +++ b/blacksheep/docs/authentication.md @@ -529,11 +529,6 @@ with signed and encrypted user data using `itsdangerous.Serializer`. The following example shows how to use the built-in `CookieAuthentication` class: -**Summary:** -- `set_cookie` is used to securely set an authentication cookie containing user claims and expiration, typically after a successful login. -- `unset_cookie` removes the authentication cookie, logging the user out. -- `request.user.claims` allows you to access the authenticated user's claims in request handlers, such as user ID, name, or roles. - ```python import secrets from datetime import datetime, timedelta, UTC @@ -590,6 +585,11 @@ async def logout(request): return response ``` +**Summary:** +- `set_cookie` is used to securely set an authentication cookie containing user claims and expiration, typically after a successful login. +- `unset_cookie` removes the authentication cookie, logging the user out. +- `request.user.claims` allows you to access the authenticated user's claims in request handlers, such as user ID, name, or roles. + /// admonition | Security recommendations type: warning