-
Notifications
You must be signed in to change notification settings - Fork 742
docs: add example for session management #3594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
DontMash
wants to merge
7
commits into
denoland:main
Choose a base branch
from
DontMash:docs/add-example-session-management
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+110
−0
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
69ebf3c
docs: add example for session management
DontMash a509f7b
chore: fix formatting
DontMash a93b887
chore: fix markdown headline rendering
DontMash ea49a11
chore: fix spelling mistake
DontMash bf54e6a
chore: add session to state in solution
DontMash dddb173
Merge branch 'main' into docs/add-example-session-management
DontMash 3279829
Merge branch 'main' into docs/add-example-session-management
DontMash File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| --- | ||
| description: | | ||
| How to manage a session using cookies. | ||
| --- | ||
|
|
||
| This example is based on a | ||
| [MDN-Guide on HTTP-Cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Cookies). | ||
| Check it out for further information. | ||
|
|
||
| Why do we want to _manage a session_? A _session_ allows us to keep track of | ||
| e.g. a user or a shoppingcart. Basically it can be used to associate data with | ||
| an identifier, or even contain data itself. Cookies are the most common solution | ||
| for session management. Since [Deno](https://deno.land) uses standard WebAPIs | ||
| like `Request` & `Response`, it is quite easy to manage a session using cookies. | ||
|
|
||
| ## Setup | ||
|
|
||
| 1. Create a [new fresh-project](https://fresh.deno.dev/docs/getting-started) or | ||
| use your own. | ||
| 2. Add the `http`-package from the standard library: | ||
| ```sh | ||
| deno add jsr:@std/http | ||
| ``` | ||
|
|
||
| ## Implementation | ||
|
|
||
| To a achieve the most basic implementation of session management we can | ||
| associate a random UUID with a request. We will use the global | ||
| [`crypto`](https://developer.mozilla.org/en-US/docs/Web/API/Window/crypto)-object | ||
| to generate a random UUID and the [`@std/http`](https://jsr.io/@std/http) | ||
| package to evaluate the cookies. | ||
|
|
||
| ### Creating a cookie | ||
|
|
||
| ```ts | ||
| import { setCookie } from "@std/http"; | ||
|
|
||
| const headers = new Headers(); | ||
| const uuid = crypto.randomUUID(); | ||
| setCookie(headers, { | ||
| name: "session", | ||
| value: uuid, | ||
| }); | ||
| ``` | ||
|
|
||
| This script will create a HTTP headers-object and assign a cookie named | ||
| _session_ with a random UUID as its value using `setCookie`. | ||
|
|
||
| Adding this headers-object to a response will make the browser attach the cookie | ||
| to the headers in every request. | ||
|
|
||
| ### Retrieving a cookie | ||
|
|
||
| ```ts | ||
| import { getCookies } from "@std/http"; | ||
|
|
||
| // arbitrary headers-object used to showcase API | ||
| const cookies = getCookies(headers); | ||
| const uuid = cookies["session"]; | ||
| ``` | ||
|
|
||
| By using `getCookie` we can retrieve the cookies of a headers-object as a | ||
| `Record<string, string>`. To access the value of a cookie we can index the | ||
| record by the cookie name as a key. | ||
|
|
||
| ## Solution | ||
|
|
||
| We can use a middleware to get the `Request` from the `Context` and create a | ||
| `Response` for it. Using the previously mentioned methods we retrieve the | ||
| cookies from the `Request`. If there is no _session_ cookie already available, | ||
| we will create a _session_ cookie and add it to the `Response`. | ||
|
|
||
| ```ts main.ts | ||
| import { getCookies, setCookie } from "@std/http"; | ||
|
|
||
| export interface State { | ||
| session: string; | ||
| } | ||
|
|
||
| // Session middleware | ||
| app.use(async (ctx: Context<State>) => { | ||
| // Retrieve current session or generate a new one | ||
| const cookies = getCookies(ctx.req.headers); | ||
| const session = cookies["session"]; | ||
| ctx.state.session = session ?? crypto.randomUUID(); | ||
|
|
||
| // Run routes/middleware | ||
| const response = await ctx.next(); | ||
|
|
||
| // Update session cookie if necessary | ||
| if (!session) { | ||
| setCookie(response.headers, { | ||
| name: "session", | ||
| value: ctx.state.session, | ||
| }); | ||
| } | ||
| return response; | ||
| }); | ||
|
|
||
| // Use `ctx.state.session` in routes/middleware | ||
| app.get( | ||
| "/", | ||
| (ctx: Context<State>) => | ||
| new Response(`Your session ID is: ${ctx.state.session}`), | ||
| ); | ||
| ``` | ||
|
|
||
| > [info]: This is a basic implementation. Expanding on this solution could mean | ||
| > adding a database to relate data to a session. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.