iron-session 8.0.0-beta.4 → 8.0.0-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -411
- package/dist/index.cjs +120 -617
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -119
- package/dist/index.d.ts +16 -119
- package/dist/index.js +102 -615
- package/dist/index.js.map +1 -1
- package/package.json +19 -23
package/README.md
CHANGED
|
@@ -1,478 +1,133 @@
|
|
|
1
|
-
# iron-session
|
|
1
|
+
# iron-session [](https://github.com/vvo/iron-session/blob/master/LICENSE) [](https://www.npmjs.com/package/iron-session) [](http://npm-stat.com/charts.html?package=iron-session)
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Bun, and more.
|
|
3
|
+
**`iron-session` is a secure, stateless, and cookie-based session library for JavaScript.**
|
|
5
4
|
|
|
6
|
-
The session data is stored in signed and encrypted cookies (
|
|
7
|
-
only be decoded by your server. There are no session ids, making sessions
|
|
8
|
-
"stateless" from the server point of view. This strategy of storing session data
|
|
9
|
-
is the same technique used by frameworks like
|
|
5
|
+
The session data is stored in signed and encrypted cookies which are decoded by your server code in a stateless fashion (= no I/O involved). This is the same technique used by frameworks like
|
|
10
6
|
[Ruby On Rails](https://guides.rubyonrails.org/security.html#session-storage).
|
|
11
7
|
|
|
12
|
-
|
|
8
|
+
<p align="center"><i>⭐️ Featured in the <a href="https://nextjs.org/docs/authentication">Next.js documentation</a></i></p>
|
|
13
9
|
|
|
14
|
-
|
|
10
|
+
## Table of Contents
|
|
15
11
|
|
|
12
|
+
- [Table of Contents](#table-of-contents)
|
|
16
13
|
- [Installation](#installation)
|
|
17
14
|
- [Usage](#usage)
|
|
18
|
-
- [
|
|
15
|
+
- [Session options](#session-options)
|
|
19
16
|
- [API](#api)
|
|
20
|
-
- [
|
|
21
|
-
- [
|
|
22
|
-
- [
|
|
23
|
-
- [
|
|
24
|
-
- [FAQ](#faq)
|
|
25
|
-
<!-- - [Contributing](#contributing) -->
|
|
26
|
-
<!-- - [License](#license) -->
|
|
17
|
+
- [`getIronSession<T>(req, res, sessionOptions): Promise<IronSession<T>>`](#getironsessiontreq-res-sessionoptions-promiseironsessiont)
|
|
18
|
+
- [`getIronSession<T>(cookieStore, sessionOptions): Promise<IronSession<T>>`](#getironsessiontcookiestore-sessionoptions-promiseironsessiont)
|
|
19
|
+
- [session.save()](#sessionsave)
|
|
20
|
+
- [session.destroy()](#sessiondestroy)
|
|
27
21
|
- [Credits](#credits)
|
|
28
22
|
- [Good Reads](#good-reads)
|
|
29
23
|
|
|
30
24
|
## Installation
|
|
31
25
|
|
|
32
26
|
```sh
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
Change the package manager to whatever you use, of course. On Deno, you can use
|
|
37
|
-
[esm.sh](https://esm.sh/):
|
|
38
|
-
|
|
39
|
-
```js
|
|
40
|
-
import { getIronSession } from 'https://esm.sh/iron-session@latest'
|
|
27
|
+
pnpm add iron-session
|
|
41
28
|
```
|
|
42
29
|
|
|
43
30
|
## Usage
|
|
44
31
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
1. Define your session options
|
|
48
|
-
1. Initialize your session with:
|
|
49
|
-
- sessionOptions and the respective parameters
|
|
50
|
-
- the type definition of your session data
|
|
51
|
-
1. Set the session data variables
|
|
52
|
-
1. Set the data to or read the data from the browser cookie storage
|
|
53
|
-
- session.save(): Set the session variables as an encrypted string to the browser cookie storage
|
|
54
|
-
- session.destroy(): Set cookie value in the browser cookie storage as an empty value to clear the cookie data
|
|
55
|
-
- Read the session variables by decrypting the encrypted string from the cookie browser storage
|
|
56
|
-
|
|
57
|
-
## Options Definitions
|
|
32
|
+
To get a session, there's a single method to know: `getIronSession`.
|
|
58
33
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
- `cookieName`, **required**: Name of the cookie to be stored
|
|
63
|
-
- `ttl`, _optional_: In seconds. Default to the equivalent of 14 days. You can set this to `0` and iron-session will compute the maximum allowed value by cookies (~70 years).
|
|
64
|
-
- `cookieOptions`, _optional_: Any option available from [jshttp/cookie#serialize](https://github.com/jshttp/cookie#cookieserializename-value-options) except for `encode` which is not a Set-Cookie Attribute. See [Mozilla Set-Cookie Attributes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#attributes) and [Chrome Cookie Fields](https://developer.chrome.com/docs/devtools/application/cookies/#fields). Default to:
|
|
34
|
+
```ts
|
|
35
|
+
// Next.js Pages with API Route and Node.js/Express/Connect.
|
|
36
|
+
import { getIronSession } from 'iron-session';
|
|
65
37
|
|
|
66
|
-
|
|
67
|
-
{
|
|
68
|
-
httpOnly: true,
|
|
69
|
-
secure: true, // true when using https, false otherwise
|
|
70
|
-
sameSite: "lax", // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite#lax
|
|
71
|
-
// The next line makes sure browser will expire cookies before seals are considered expired by the server. It also allows for clock difference of 60 seconds maximum between servers and clients.
|
|
72
|
-
maxAge: (ttl === 0 ? 2147483647 : ttl) - 60,
|
|
73
|
-
path: "/",
|
|
74
|
-
// other options:
|
|
75
|
-
// domain, if you want the cookie to be valid for the whole domain and subdomains, use domain: example.com
|
|
76
|
-
// expires, there should be no need to use this option, maxAge takes precedence
|
|
77
|
-
// ...
|
|
38
|
+
export function get(req, res) {
|
|
39
|
+
const session = getIronSession(req, res, { password: "...", cookieName: "..." });
|
|
78
40
|
}
|
|
79
|
-
```
|
|
80
41
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
### Type Definitions from iron-session/dist/index.node.d.cts
|
|
86
|
-
|
|
87
|
-
#### IronSessionOptions
|
|
88
|
-
|
|
89
|
-
```ts
|
|
90
|
-
interface IronSessionOptions {
|
|
91
|
-
/**
|
|
92
|
-
* The cookie name that will be used inside the browser. Make sure it's unique
|
|
93
|
-
* given your application.
|
|
94
|
-
*
|
|
95
|
-
* @example 'vercel-session'
|
|
96
|
-
*/
|
|
97
|
-
cookieName: string;
|
|
98
|
-
/**
|
|
99
|
-
* The password(s) that will be used to encrypt the cookie. Can either be a string
|
|
100
|
-
* or an object.
|
|
101
|
-
*
|
|
102
|
-
* When you provide multiple passwords then all of them will be used to decrypt
|
|
103
|
-
* the cookie. But only the most recent (`= highest key`, `2` in the example)
|
|
104
|
-
* password will be used to encrypt the cookie. This allows password rotation.
|
|
105
|
-
*
|
|
106
|
-
* @example { 1: 'password-1', 2: 'password-2' }
|
|
107
|
-
*/
|
|
108
|
-
password: Password;
|
|
109
|
-
/**
|
|
110
|
-
* The time (in seconds) that the session will be valid for. Also sets the
|
|
111
|
-
* `max-age` attribute of the cookie automatically (`= ttl - 60s`, so that the
|
|
112
|
-
* cookie always expire before the session).
|
|
113
|
-
*
|
|
114
|
-
* `ttl = 0` means no expiration.
|
|
115
|
-
*
|
|
116
|
-
* @default 1209600
|
|
117
|
-
*/
|
|
118
|
-
ttl?: number;
|
|
119
|
-
/**
|
|
120
|
-
* The options that will be passed to the cookie library.
|
|
121
|
-
*
|
|
122
|
-
* If you want to use "session cookies" (cookies that are deleted when the browser
|
|
123
|
-
* is closed) then you need to pass `cookieOptions: { maxAge: undefined }`
|
|
124
|
-
*
|
|
125
|
-
* @see https://github.com/jshttp/cookie#options-1
|
|
126
|
-
*/
|
|
127
|
-
cookieOptions?: CookieOptions;
|
|
42
|
+
export function post(req, res) {
|
|
43
|
+
const session = getIronSession(req, res, { password: "...", cookieName: "..." });
|
|
44
|
+
session.username = "Alison";
|
|
45
|
+
await session.save();
|
|
128
46
|
}
|
|
129
47
|
```
|
|
130
48
|
|
|
131
|
-
##### CookieOptions
|
|
132
|
-
|
|
133
49
|
```ts
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
|
|
138
|
-
* @see https://developer.chrome.com/docs/devtools/application/cookies/
|
|
139
|
-
*/
|
|
140
|
-
type CookieOptions = Omit<CookieSerializeOptions, 'encode'>
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
##### CookieSerializeOptions
|
|
50
|
+
// Next.js App Router with route handlers
|
|
51
|
+
import { cookies } from 'next/header';
|
|
52
|
+
import { getIronSession } from 'iron-session';
|
|
144
53
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Specifies the value for the {@link https://tools.ietf.org/html/rfc6265#section-5.2.3|Domain Set-Cookie attribute}. By default, no
|
|
149
|
-
* domain is set, and most clients will consider the cookie to apply to only
|
|
150
|
-
* the current domain.
|
|
151
|
-
*/
|
|
152
|
-
domain?: string | undefined;
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Specifies a function that will be used to encode a cookie's value. Since
|
|
156
|
-
* value of a cookie has a limited character set (and must be a simple
|
|
157
|
-
* string), this function can be used to encode a value into a string suited
|
|
158
|
-
* for a cookie's value.
|
|
159
|
-
*
|
|
160
|
-
* The default function is the global `encodeURIComponent`, which will
|
|
161
|
-
* encode a JavaScript string into UTF-8 byte sequences and then URL-encode
|
|
162
|
-
* any that fall outside of the cookie range.
|
|
163
|
-
*/
|
|
164
|
-
encode?(value: string): string;
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Specifies the `Date` object to be the value for the {@link https://tools.ietf.org/html/rfc6265#section-5.2.1|`Expires` `Set-Cookie` attribute}. By default,
|
|
168
|
-
* no expiration is set, and most clients will consider this a "non-persistent cookie" and will delete
|
|
169
|
-
* it on a condition like exiting a web browser application.
|
|
170
|
-
*
|
|
171
|
-
* *Note* the {@link https://tools.ietf.org/html/rfc6265#section-5.3|cookie storage model specification}
|
|
172
|
-
* states that if both `expires` and `maxAge` are set, then `maxAge` takes precedence, but it is
|
|
173
|
-
* possible not all clients by obey this, so if both are set, they should
|
|
174
|
-
* point to the same date and time.
|
|
175
|
-
*/
|
|
176
|
-
expires?: Date | undefined;
|
|
177
|
-
/**
|
|
178
|
-
* Specifies the boolean value for the {@link https://tools.ietf.org/html/rfc6265#section-5.2.6|`HttpOnly` `Set-Cookie` attribute}.
|
|
179
|
-
* When truthy, the `HttpOnly` attribute is set, otherwise it is not. By
|
|
180
|
-
* default, the `HttpOnly` attribute is not set.
|
|
181
|
-
*
|
|
182
|
-
* *Note* be careful when setting this to true, as compliant clients will
|
|
183
|
-
* not allow client-side JavaScript to see the cookie in `document.cookie`.
|
|
184
|
-
*/
|
|
185
|
-
httpOnly?: boolean | undefined;
|
|
186
|
-
/**
|
|
187
|
-
* Specifies the number (in seconds) to be the value for the `Max-Age`
|
|
188
|
-
* `Set-Cookie` attribute. The given number will be converted to an integer
|
|
189
|
-
* by rounding down. By default, no maximum age is set.
|
|
190
|
-
*
|
|
191
|
-
* *Note* the {@link https://tools.ietf.org/html/rfc6265#section-5.3|cookie storage model specification}
|
|
192
|
-
* states that if both `expires` and `maxAge` are set, then `maxAge` takes precedence, but it is
|
|
193
|
-
* possible not all clients by obey this, so if both are set, they should
|
|
194
|
-
* point to the same date and time.
|
|
195
|
-
*/
|
|
196
|
-
maxAge?: number | undefined;
|
|
197
|
-
/**
|
|
198
|
-
* Specifies the value for the {@link https://tools.ietf.org/html/rfc6265#section-5.2.4|`Path` `Set-Cookie` attribute}.
|
|
199
|
-
* By default, the path is considered the "default path".
|
|
200
|
-
*/
|
|
201
|
-
path?: string | undefined;
|
|
202
|
-
/**
|
|
203
|
-
* Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1].
|
|
204
|
-
*
|
|
205
|
-
* - `'low'` will set the `Priority` attribute to `Low`.
|
|
206
|
-
* - `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set.
|
|
207
|
-
* - `'high'` will set the `Priority` attribute to `High`.
|
|
208
|
-
*
|
|
209
|
-
* More information about the different priority levels can be found in
|
|
210
|
-
* [the specification][rfc-west-cookie-priority-00-4.1].
|
|
211
|
-
*
|
|
212
|
-
* **note** This is an attribute that has not yet been fully standardized, and may change in the future.
|
|
213
|
-
* This also means many clients may ignore this attribute until they understand it.
|
|
214
|
-
*/
|
|
215
|
-
priority?: 'low' | 'medium' | 'high' | undefined;
|
|
216
|
-
/**
|
|
217
|
-
* Specifies the boolean or string to be the value for the {@link https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7|`SameSite` `Set-Cookie` attribute}.
|
|
218
|
-
*
|
|
219
|
-
* - `true` will set the `SameSite` attribute to `Strict` for strict same
|
|
220
|
-
* site enforcement.
|
|
221
|
-
* - `false` will not set the `SameSite` attribute.
|
|
222
|
-
* - `'lax'` will set the `SameSite` attribute to Lax for lax same site
|
|
223
|
-
* enforcement.
|
|
224
|
-
* - `'strict'` will set the `SameSite` attribute to Strict for strict same
|
|
225
|
-
* site enforcement.
|
|
226
|
-
* - `'none'` will set the SameSite attribute to None for an explicit
|
|
227
|
-
* cross-site cookie.
|
|
228
|
-
*
|
|
229
|
-
* More information about the different enforcement levels can be found in {@link https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7|the specification}.
|
|
230
|
-
*
|
|
231
|
-
* *note* This is an attribute that has not yet been fully standardized, and may change in the future. This also means many clients may ignore this attribute until they understand it.
|
|
232
|
-
*/
|
|
233
|
-
sameSite?: true | false | 'lax' | 'strict' | 'none' | undefined;
|
|
234
|
-
/**
|
|
235
|
-
* Specifies the boolean value for the {@link https://tools.ietf.org/html/rfc6265#section-5.2.5|`Secure` `Set-Cookie` attribute}. When truthy, the
|
|
236
|
-
* `Secure` attribute is set, otherwise it is not. By default, the `Secure` attribute is not set.
|
|
237
|
-
*
|
|
238
|
-
* *Note* be careful when setting this to `true`, as compliant clients will
|
|
239
|
-
* not send the cookie back to the server in the future if the browser does
|
|
240
|
-
* not have an HTTPS connection.
|
|
241
|
-
*/
|
|
242
|
-
secure?: boolean | undefined;
|
|
54
|
+
export function GET() {
|
|
55
|
+
const session = getIronSession(cookies(), { password: "...", cookieName: "..." });
|
|
243
56
|
}
|
|
244
57
|
|
|
58
|
+
export function POST() {
|
|
59
|
+
const session = getIronSession(req, res, { password: "...", cookieName: "..." });
|
|
60
|
+
session.username = "Alison";
|
|
61
|
+
await session.save();
|
|
62
|
+
}
|
|
245
63
|
```
|
|
246
64
|
|
|
247
|
-
## API
|
|
248
|
-
|
|
249
|
-
## Iron Session Object
|
|
250
|
-
|
|
251
|
-
### getIronSession(req: Request | IncomingMessage, res: Response | ServerResponse<IncomingMessage>, userSessionOptions: IronSessionOptions): Promise<IronSession<T>>
|
|
252
|
-
|
|
253
|
-
```ts
|
|
254
|
-
const session = getIronSession<IronSessionData>(req, res, sessionOptions)
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
The API Route Handler that uses `getIronSession` and returns the Response needs to be called from a client-side environment (ie. a 'use client' file).
|
|
258
|
-
|
|
259
|
-
### getServerActionIronSession(userSessionOptions: IronSessionOptions, cookieHandler: ICookieHandler): Promise<IronSession<T>>
|
|
260
|
-
|
|
261
|
-
```ts
|
|
262
|
-
const session = getServerActionIronSession<IronSessionData>(sessionOptions, cookies())
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
The `getServerActionIronSession` implementation uses the `cookies()` function from next/headers to set the cookies so that Iron Session can be used in NextJS Server Actions and React Server Components in a server-side environment (ie. a 'use server' file).
|
|
266
|
-
|
|
267
|
-
## Iron Session Functions
|
|
268
|
-
|
|
269
|
-
### session.save(saveOptions?: OverridableOptions)
|
|
270
|
-
|
|
271
|
-
Saves the session and sets the cookie header to be sent once the response is sent.
|
|
272
|
-
|
|
273
|
-
```ts
|
|
274
|
-
await session.save()
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
### session.destroy(destroyOptions?: OverridableOptions)
|
|
278
|
-
|
|
279
|
-
Empties the session object and sets the cookie header to be sent once the response is sent. The browser will then set the cookie value as an empty value.
|
|
280
|
-
|
|
281
65
|
```ts
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
Upon calling either `session.save()` or `session.destroy()` the session values are saved to the browser cookie storage.
|
|
286
|
-
|
|
287
|
-
## Iron Session Options
|
|
288
|
-
|
|
289
|
-
### Default Options
|
|
66
|
+
// Next.js App Router with server component or server action
|
|
67
|
+
import { cookies } from 'next/header';
|
|
68
|
+
import { getIronSession } from 'iron-session';
|
|
290
69
|
|
|
291
|
-
|
|
292
|
-
const
|
|
293
|
-
ttl: fourteenDaysInSeconds,
|
|
294
|
-
cookieOptions: { httpOnly: true, secure: true, sameSite: 'lax', path: '/' },
|
|
70
|
+
async function getIronSession() {
|
|
71
|
+
const session = await getIronSession(cookies(), { password: "...", cookieName: "..." });
|
|
295
72
|
}
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
### User Session Options
|
|
299
|
-
|
|
300
|
-
You may apply options during the Iron Session object initialization. These options will superseded and override any options set in Default Options. For example: refer to `cookieOptions` in `lib/session.ts` in the below [NextJS Example](#nextjs-example).
|
|
301
73
|
|
|
302
|
-
|
|
74
|
+
function Profile() {
|
|
75
|
+
const session = await getIronSession();
|
|
303
76
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
For example:
|
|
307
|
-
|
|
308
|
-
```ts
|
|
309
|
-
type OverridableOptions = {
|
|
310
|
-
ttl?: number;
|
|
311
|
-
cookieOptions?: CookieOptions;
|
|
77
|
+
return <div>{session.username}</div>;
|
|
312
78
|
}
|
|
313
79
|
```
|
|
314
80
|
|
|
315
|
-
```ts
|
|
316
|
-
await session.save({ cookieOptions: { priority: 'high'} })
|
|
317
|
-
```
|
|
318
81
|
|
|
319
|
-
##
|
|
82
|
+
## Session options
|
|
320
83
|
|
|
321
|
-
|
|
84
|
+
Two options are required: `password` and `cookieName`. Everything else is automatically computed and usually doesn't need to be changed.
|
|
322
85
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
import { cookies } from 'next/headers';
|
|
329
|
-
|
|
330
|
-
export const sessionOptions: IronSessionOptions = {
|
|
331
|
-
password: 'change-this-this-is-not-a-secure-password',
|
|
332
|
-
cookieName: 'cookieNameInBrowser',
|
|
333
|
-
cookieOptions: {
|
|
334
|
-
secure: process.env.NODE_ENV === 'production',
|
|
335
|
-
},
|
|
336
|
-
}
|
|
86
|
+
- `password`, **required**: Private key used to encrypt the cookie. It has to be at least 32 characters long. Use <https://1password.com/password-generator/> to generate strong passwords. `password` can be either a `string` or an `array` of objects like this: `[{id: 2, password: "..."}, {id: 1, password: "..."}]` to allow for password rotation.
|
|
87
|
+
- `cookieName`, **required**: Name of the cookie to be stored
|
|
88
|
+
- `ttl`, _optional_: In seconds. Default to the equivalent of 14 days. You can set this to `0` and iron-session will compute the maximum allowed value by cookies.
|
|
89
|
+
- `cookieOptions`, _optional_: Any option available from [jshttp/cookie#serialize](https://github.com/jshttp/cookie#cookieserializename-value-options) except for `encode` which is not a Set-Cookie Attribute. See [Mozilla Set-Cookie Attributes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#attributes) and [Chrome Cookie Fields](https://developer.chrome.com/docs/devtools/application/cookies/#fields). Default to:
|
|
337
90
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
91
|
+
```js
|
|
92
|
+
{
|
|
93
|
+
httpOnly: true,
|
|
94
|
+
secure: true, // set this to false in local (non-HTTPS) development
|
|
95
|
+
sameSite: "lax",// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite#lax
|
|
96
|
+
maxAge: (ttl === 0 ? 2147483647 : ttl) - 60, // Expire cookie before the session expires.
|
|
97
|
+
path: "/",
|
|
341
98
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
const getSession = async (req: Request, res: Response) => {
|
|
345
|
-
const session = getIronSession<IronSessionData>(req, res, sessionOptions)
|
|
346
|
-
return session
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
const getServerActionSession = async () => {
|
|
350
|
-
const session = getServerActionIronSession<IronSessionData>(sessionOptions, cookies())
|
|
351
|
-
return session
|
|
352
|
-
}
|
|
99
|
+
```
|
|
353
100
|
|
|
354
|
-
|
|
355
|
-
getSession,
|
|
356
|
-
getServerActionSession
|
|
357
|
-
}
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
### getIronSession
|
|
361
|
-
|
|
362
|
-
#### src/app/clientActions.ts
|
|
363
|
-
|
|
364
|
-
```ts
|
|
365
|
-
'use client'
|
|
366
|
-
|
|
367
|
-
export const submitCookieToStorageRouteHandler = async (cookie: string) => {
|
|
368
|
-
await fetch('http://localhost:3000/api/submitIronSessionCookie', {
|
|
369
|
-
method: 'POST',
|
|
370
|
-
body: JSON.stringify({
|
|
371
|
-
cookie,
|
|
372
|
-
}),
|
|
373
|
-
headers: {
|
|
374
|
-
'Content-Type': 'application/json',
|
|
375
|
-
},
|
|
376
|
-
})
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
export const readCookieFromStorageRouteHandler = async (): Promise<string> => {
|
|
380
|
-
const responseWithCookieFromStorage = await fetch('http://localhost:3000/api/readIronSessionCookie', {
|
|
381
|
-
method: 'GET',
|
|
382
|
-
headers: {
|
|
383
|
-
'Content-Type': 'application/json',
|
|
384
|
-
},
|
|
385
|
-
})
|
|
386
|
-
const data = await responseWithCookieFromStorage.json();
|
|
387
|
-
const cookieValue = data?.cookieInStorage || 'No Cookie In Storage'
|
|
388
|
-
return cookieValue
|
|
389
|
-
}
|
|
390
|
-
```
|
|
101
|
+
## API
|
|
391
102
|
|
|
392
|
-
|
|
103
|
+
### `getIronSession<T>(req, res, sessionOptions): Promise<IronSession<T>>`
|
|
393
104
|
|
|
394
105
|
```ts
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
export async function POST(request: Request) {
|
|
398
|
-
try {
|
|
399
|
-
const requestBody = await request.json()
|
|
400
|
-
const { cookie }: { cookie: string } = requestBody
|
|
401
|
-
const response = new Response()
|
|
402
|
-
const session = await getSession(request, response)
|
|
403
|
-
session.cookieVariable = cookie
|
|
404
|
-
await session.save()
|
|
405
|
-
return response
|
|
406
|
-
} catch (error: unknown) {
|
|
407
|
-
console.error((error as Error).message)
|
|
408
|
-
return new Response(JSON.stringify({ message: (error as Error).message }), { status: 500 })
|
|
409
|
-
}
|
|
410
|
-
}
|
|
106
|
+
const session = getIronSession<SessionData>(req, res, sessionOptions);
|
|
411
107
|
```
|
|
412
108
|
|
|
413
|
-
|
|
109
|
+
### `getIronSession<T>(cookieStore, sessionOptions): Promise<IronSession<T>>`
|
|
414
110
|
|
|
415
111
|
```ts
|
|
416
|
-
|
|
417
|
-
import { getSession } from '../../../../lib/session'
|
|
418
|
-
|
|
419
|
-
export async function GET(request: Request, response: Response) {
|
|
420
|
-
try {
|
|
421
|
-
const session = await getSession(request, response)
|
|
422
|
-
const cookeValue = session.cookieVariable || 'No Cookie Stored!'
|
|
423
|
-
return NextResponse.json({ cookieInStorage: cookeValue })
|
|
424
|
-
} catch (error: unknown) {
|
|
425
|
-
console.error((error as Error).message)
|
|
426
|
-
return new Response(JSON.stringify({ message: (error as Error).message }), { status: 500 })
|
|
427
|
-
}
|
|
428
|
-
}
|
|
112
|
+
const session = getIronSession<SessionData>(cookies(), sessionOptions);
|
|
429
113
|
```
|
|
430
114
|
|
|
431
|
-
###
|
|
115
|
+
### session.save()
|
|
432
116
|
|
|
433
|
-
|
|
117
|
+
Saves the session.
|
|
434
118
|
|
|
435
119
|
```ts
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
import { getServerActionSession } from '../../lib/session'
|
|
439
|
-
|
|
440
|
-
export const submitCookieToStorageServerAction = async (cookie: string) => {
|
|
441
|
-
const session = await getServerActionSession()
|
|
442
|
-
session.cookieVariable = cookie
|
|
443
|
-
await session.save()
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
export const readCookieFromStorageServerAction = async (): Promise<string> => {
|
|
447
|
-
const session = await getServerActionSession()
|
|
448
|
-
return session.cookieVariable || 'No Cookie Stored!'
|
|
449
|
-
}
|
|
120
|
+
await session.save()
|
|
450
121
|
```
|
|
451
122
|
|
|
452
|
-
|
|
123
|
+
### session.destroy()
|
|
453
124
|
|
|
454
|
-
|
|
455
|
-
/** @type {import('next').NextConfig} */
|
|
456
|
-
const nextConfig = {
|
|
457
|
-
experimental: {
|
|
458
|
-
serverActions: true,
|
|
459
|
-
},
|
|
460
|
-
}
|
|
125
|
+
Destroys the session.
|
|
461
126
|
|
|
462
|
-
|
|
127
|
+
```ts
|
|
128
|
+
await session.destroy()
|
|
463
129
|
```
|
|
464
130
|
|
|
465
|
-
## FAQ
|
|
466
|
-
|
|
467
|
-
### When should I use getIronSession or getServerActionIronSession?
|
|
468
|
-
|
|
469
|
-
Use `getIronSession` when you wish to use Iron Session in a client-side environment with API Route Handlers and use `getServerActionIronSession` when you wish to use Iron Session in a server-side environment with Server Components.
|
|
470
|
-
|
|
471
|
-
For NextJS projects using App Router with Server Actions enabled in their `next.config.js` file, using `getServerActionIronSession` is preferable for two reasons:
|
|
472
|
-
|
|
473
|
-
- allows Iron Session to be called and used from a server-side environment
|
|
474
|
-
- allows for more concise code. Server Actions can be called directly from your components without the need for a manually created API route. You can see the smaller amount of code used for `getServerActionIronSession` compared to `getIronSession` in the example.
|
|
475
|
-
|
|
476
131
|
## Credits
|
|
477
132
|
|
|
478
133
|
- [Eran Hammer and hapi.js contributors](https://github.com/hapijs/iron/graphs/contributors)
|