You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Cookies are fundamental for maintaining state in web applications. The `Genie.Cookies` module provides a secure and flexible interface for handling them, including automatic encryption and protection against common attacks (XSS/CSRF).
3
+
Cookies are fundamental for maintaining state in web applications. The `Genie.Cookies` module provides a secure and flexible interface for handling them, including automatic encryption, configuration defaults, and protection against common attacks (XSS/CSRF).
4
4
5
5
## Table of Contents
6
6
7
+
-[Quick Start: Choose Your Path](#quick-start-choose-your-path)
7
8
-[Introduction](#introduction)
8
9
-[Basic Usage](#basic-usage)
9
10
-[Setting Cookies](#setting-cookies)
10
11
-[Reading Cookies](#reading-cookies)
11
-
-[Removing Cookies](#removing-cookies)
12
+
-[Removing Cookies (Logout)](#removing-cookies-logout)
12
13
-[Attributes and Security](#attributes-and-security)
|**Traditional HTML** (Genie views, redirects, forms) |[Working with Sessions](Working_with_Sessions.md)*(in development)*| Only for simple preferences like `"theme=dark"` or `"language=en"`|
24
+
|**SPA Backend** (React/Vue/Quasar API on different domain) |**This Guide** + [Cookie Security](Working_with_Cookies_Security.md)| JWT tokens, CORS cookies, HttpOnly auth |
25
+
|**Hybrid** (Genie views + some JSON APIs) |[Sessions](Working_with_Sessions.md)*(in development)* first | When you need fine-grained cookie control for specific endpoints |
26
+
27
+
> **TL;DR:** Building a traditional Genie app with `@yield` and redirects? Use sessions (coming soon) β they use cookies internally and handle all the security for you. For now, this guide covers direct cookie control needed for API backends.
28
+
29
+
---
30
+
16
31
## Introduction
17
32
18
-
Genie encrypts cookie values by default using `Genie.Encryption`. This ensures that sensitive data is not exposed in plain text in the client's browser.
33
+
Genie's cookie system is designed to be **secure by default**:
34
+
1.**Encryption:** Values are encrypted using `Genie.Encryption` unless specified otherwise.
35
+
2.**Defaults:** Global attributes (like `HttpOnly`) can be configured once and applied everywhere.
36
+
3.**Auto-Correction:** The system automatically fixes insecure configurations (like `SameSite=None` without `Secure`).
19
37
20
38
## Basic Usage
21
39
22
40
### Setting Cookies
23
41
24
-
The `set!` function modifies an `HTTP.Response` object. In practice, you usually create a content response (such as HTML or JSON) using Genie's renderers and attach the cookie to it before returning.
42
+
The `set!` function modifies an `HTTP.Response` object. In practice, you usually create a content response (such as HTML or JSON) and attach the cookie to it.
43
+
44
+
**Clean Style (Relying on Config Defaults):**
45
+
If you have configured your defaults in `config/env/*.jl`, your code stays clean:
25
46
26
47
```julia
27
-
using Genie, Genie.Cookies, Genie.Renderer.Json, Genie.Renderer.Html
48
+
using Genie, Genie.Cookies, Genie.Renderer.Json
28
49
29
50
route("/login") do
30
-
# 1. Create the response with the desired content
31
-
res =html("<h1>Welcome to the System</h1>")
51
+
# 1. Create response
52
+
res =json(Dict("status"=>"logged_in"))
32
53
33
-
# 2. Attach the cookie to the response (Encrypted by default)
34
-
Genie.Cookies.set!(res, "user_id", "12345")
54
+
# 2. Set cookie (inherits HttpOnly, Path, SameSite from config)
Use the `get` function to read cookies from the request object (`@request`). If the cookie was encrypted when set (default), it will be automatically decrypted upon reading.
73
+
Use the `get` function to read cookies from the request object (`@request` or passed explicitly). If the cookie was encrypted when set (default), it is automatically decrypted.
48
74
49
75
```julia
50
76
route("/dashboard") do
@@ -58,105 +84,97 @@ route("/dashboard") do
58
84
end
59
85
end
60
86
61
-
# Reading with a default value if the cookie does not exist
You can pass a dictionary of attributes to control cookie behavior. This is crucial for application security.
112
+
While you can set attributes manually, we recommend defining them in [Cookie Configuration](Working_with_Cookies_Configuration.md) to keep your app DRY.
> **Auto-Secure Feature:** If you set `samesite` to `"none"` (common for SPAs) but forget `secure`, Genie automatically enables `secure` to prevent browser errors.
114
127
115
128
## SPA Integration (Quasar/Vue/React)
116
129
117
-
If you are using Genie as an API for a frontend (Quasar, React, Vue), the recommended security pattern is to return JSON in the response body and set the authentication token in an `HttpOnly` cookie.
130
+
If you use Genie as an API for a frontend, the recommended security pattern is: **Return JSON, Set HttpOnly Cookie.**
118
131
119
132
### Backend (Genie):
120
133
121
134
```julia
122
135
route("/api/login", method = POST) do
123
-
# ... user validation logic ...
136
+
# ... user validation ...
124
137
125
-
# Return JSON so the frontend knows the operation succeeded
126
-
res =json(Dict("user"=>"Admin", "redirect"=>"/dashboard"))
138
+
res =json(Dict("user"=>"Admin"))
127
139
128
-
# Set the token in a secure cookie that JS cannot read
129
-
# The browser will automatically send this cookie in subsequent requests
On the frontend, you do not need to read the cookie manually. Just ensure that the HTTP client (e.g., Axios) is configured to send credentials (cookies):
148
+
You do not need to read the cookie manually. Just configure the client to send credentials:
141
149
142
150
```javascript
143
-
// Axios configuration
144
151
axios.defaults.withCredentials=true;
145
152
```
146
153
147
154
## Note on Sessions
148
155
149
-
While it is technically possible to implement sessions manually using`Genie.Cookies`, it is **not recommended**.
156
+
While you *can* build sessions manually with`Genie.Cookies`, it is **not recommended**.
150
157
151
-
Genie has a robust, dedicated module for this: `Genie.Sessions`. Use `Genie.Cookies` for:
152
-
- Simple data
153
-
- UI preferences (light/dark mode)
154
-
- Tracking
155
-
- Flags
156
-
157
-
Use `Genie.Sessions` for:
158
-
- User login
158
+
Use the dedicated **`Genie.Sessions`** module for:
159
+
- User login state
159
160
- Shopping carts
160
-
- Complex state data
161
+
- Complex data storage
162
+
163
+
`Genie.Sessions` uses `Genie.Cookies` internally to manage the session ID securely, abstracting away the storage details. Use `Genie.Cookies` directly only for simple flags (e.g., "cookie_consent=true") or lightweight preferences.
0 commit comments