Skip to content

Commit 0de1c67

Browse files
Added graphs to document authentication flow
1 parent e76f5b9 commit 0de1c67

15 files changed

+3398
-0
lines changed

README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,43 @@ disadvantage is that it requires an extra round trip to the database to
2323
fetch the updated data, and re-rendering the entire page template may be
2424
less efficient than a partial page update on the client side.
2525

26+
### Authentication Flow
27+
28+
This application implements a comprehensive authentication system with
29+
security best practices. The diagrams below show the main authentication
30+
flows and security measures.
31+
32+
#### Registration and Login Flow
33+
34+
![Registration and Login Flow](static/auth_flow.png)
35+
36+
#### Password Reset Flow
37+
38+
![Password Reset Flow](static/reset_flow.png)
39+
40+
The authentication system implements multiple security measures:
41+
42+
1. **Token Security**:
43+
- JWT-based with separate access/refresh tokens
44+
- Strict expiry times (30 min access, 30 day refresh)
45+
- Token type validation
46+
- HTTP-only cookies
47+
- Secure flag enabled
48+
- SameSite=strict restriction
49+
2. **Password Security**:
50+
- Strong password requirements enforced
51+
- Bcrypt hashing with random salt
52+
- Password reset tokens are single-use
53+
- Reset tokens have expiration
54+
3. **Cookie Security**:
55+
- HTTP-only prevents JavaScript access
56+
- Secure flag ensures HTTPS only
57+
- Strict SameSite prevents CSRF
58+
4. **Error Handling**:
59+
- Validation errors properly handled
60+
- Security-related errors don’t leak information
61+
- Comprehensive error logging
62+
2663
### Install development dependencies in a VSCode Dev Container
2764

2865
If you use VSCode with Docker to develop in a container, the following

README.qmd

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,132 @@ dot.render('static/webapp_flow', format='png', cleanup=True)
5050

5151
The advantage of the PRG pattern is that it is very straightforward to implement and keeps most of the rendering logic on the server side. The disadvantage is that it requires an extra round trip to the database to fetch the updated data, and re-rendering the entire page template may be less efficient than a partial page update on the client side.
5252

53+
### Authentication Flow
54+
55+
This application implements a comprehensive authentication system with security best practices. The diagrams below show the main authentication flows and security measures.
56+
57+
#### Registration and Login Flow
58+
59+
``` {python}
60+
#| echo: false
61+
#| include: false
62+
from graphviz import Digraph
63+
64+
# Create graph for registration/login
65+
auth = Digraph(name='auth_flow')
66+
auth.attr(rankdir='TB')
67+
auth.attr('node', shape='box', style='rounded')
68+
69+
# Client-side nodes
70+
with auth.subgraph(name='cluster_client') as client:
71+
client.attr(label='Client')
72+
client.node('register_form', 'Submit registration')
73+
client.node('login_form', 'Submit login')
74+
client.node('store_cookies', 'Store secure cookies')
75+
76+
# Server-side nodes
77+
with auth.subgraph(name='cluster_server') as server:
78+
server.attr(label='Server')
79+
# Registration path
80+
server.node('validate_register', 'Validate registration data')
81+
server.node('hash_new', 'Hash new password')
82+
server.node('store_user', 'Store user in database')
83+
84+
# Login path
85+
server.node('validate_login', 'Validate login data')
86+
server.node('verify_password', 'Verify password hash')
87+
server.node('fetch_user', 'Fetch user from database')
88+
89+
# Common path
90+
server.node('generate_tokens', 'Generate JWT tokens')
91+
92+
# Registration path
93+
auth.edge('register_form', 'validate_register', 'POST /register')
94+
auth.edge('validate_register', 'hash_new')
95+
auth.edge('hash_new', 'store_user')
96+
auth.edge('store_user', 'generate_tokens', 'Success')
97+
98+
# Login path
99+
auth.edge('login_form', 'validate_login', 'POST /login')
100+
auth.edge('validate_login', 'fetch_user')
101+
auth.edge('fetch_user', 'verify_password')
102+
auth.edge('verify_password', 'generate_tokens', 'Success')
103+
104+
# Common path
105+
auth.edge('generate_tokens', 'store_cookies', 'Set-Cookie')
106+
107+
auth.render('static/auth_flow', format='png', cleanup=True)
108+
```
109+
110+
![Registration and Login Flow](static/auth_flow.png)
111+
112+
#### Password Reset Flow
113+
114+
``` {python}
115+
#| echo: false
116+
#| include: false
117+
from graphviz import Digraph
118+
119+
# Create graph for password reset
120+
reset = Digraph(name='reset_flow')
121+
reset.attr(rankdir='TB')
122+
reset.attr('node', shape='box', style='rounded')
123+
124+
# Client-side nodes
125+
reset.attr(label='Client')
126+
reset.node('forgot', 'User submits forgot password form')
127+
reset.node('reset', 'User submits reset password form')
128+
reset.node('email_client', 'User clicks reset link')
129+
130+
# Server-side nodes
131+
reset.attr(label='Server')
132+
reset.node('validate', 'Validation')
133+
reset.node('token_gen', 'Generate reset token')
134+
reset.node('hash', 'Hash password')
135+
reset.node('email_server', 'Send email with Resend')
136+
reset.node('db', 'Database', shape='cylinder')
137+
138+
# Add edges with labels
139+
reset.edge('forgot', 'token_gen', 'POST')
140+
reset.edge('token_gen', 'db', 'Store')
141+
reset.edge('token_gen', 'email_server', 'Add email/token as URL parameter')
142+
reset.edge('email_server', 'email_client')
143+
reset.edge('email_client', 'reset', 'Set email/token as form input')
144+
reset.edge('reset', 'validate', 'POST')
145+
reset.edge('validate', 'hash')
146+
reset.edge('hash', 'db', 'Update')
147+
148+
reset.render('static/reset_flow', format='png', cleanup=True)
149+
```
150+
151+
![Password Reset Flow](static/reset_flow.png)
152+
153+
The authentication system implements multiple security measures:
154+
155+
1. **Token Security**:
156+
- JWT-based with separate access/refresh tokens
157+
- Strict expiry times (30 min access, 30 day refresh)
158+
- Token type validation
159+
- HTTP-only cookies
160+
- Secure flag enabled
161+
- SameSite=strict restriction
162+
163+
2. **Password Security**:
164+
- Strong password requirements enforced
165+
- Bcrypt hashing with random salt
166+
- Password reset tokens are single-use
167+
- Reset tokens have expiration
168+
169+
3. **Cookie Security**:
170+
- HTTP-only prevents JavaScript access
171+
- Secure flag ensures HTTPS only
172+
- Strict SameSite prevents CSRF
173+
174+
4. **Error Handling**:
175+
- Validation errors properly handled
176+
- Security-related errors don't leak information
177+
- Comprehensive error logging
178+
53179
### Install development dependencies in a VSCode Dev Container
54180

55181
If you use VSCode with Docker to develop in a container, the following VSCode Dev Container configuration will install all dependencies:

0 commit comments

Comments
 (0)