Stateful session middleware for Hono. Works on Cloudflare Workers, Node.js, Bun, Deno, etc.
ステートフルなセッションを提供するHonoのミドルウェアです。Cloudflare WorkersやNode.js、Bunなどの環境で動作します。
Supported | Runtime | Tested |
---|---|---|
✔️ | Bun | ✔️ |
✔️ | Cloudflare Workers | ✔️ |
✔️ | Cloudflare Pages (Functions) | |
✔️ | Node.js | ✔️ |
✔️ | Deno (with Redis) | ✔️ |
✔️ | Deno KV | ✔️ |
npm install hono-kv-session
SESSION
.$ wrangler kv:namespace create SESSION
1.
to wrangler.toml
.{ binding = "SESSION", id = "b80d8fc5924d43ba85b56aa6b6dbb1c3" }
# systemctl start redis-server
--unstable
flag, as below:
$ deno run --allow-net --watch --unstable app.ts
$ wrangler d1 create session-db
database_id
to wrangler.toml
.
[[ d1_databases ]]
binding = "SESSION_DB"
database_name = "session-db"
database_id = "<Unique ID for Your Database Here>"
preview_database_id = "local"
$ npm run d1:init
You can see the sample code in the ./dev
directory in Github.
Cloudflare Workers, Cloudflare Pages
import { kvClient } from 'hono-kv-session/cloudflare';
app.use('*', kvClient());
Node.js, Bun, Deno (with Redis)
import { kvClient } from 'hono-kv-session/redis';
app.use('*', kvClient());
// or You can set any node-redis's createClient() options
app.use('*', kvClient({
url: 'redis://alice:foobared@awesome.redis.server:6380'
}));
Deno KV
import { kvClient } from 'https://deno.land/x/hono_kv_session/kv/denokv.js';
app.use('*', kvClient());
Cloudflare D1
import { kvClient } from 'hono-kv-session/d1';
app.use('*', kvClient());
Set SessionManager()
middleware.
import { SessionManager, createSession, deleteSession } from 'hono-kv-session' // If you are using Deno, replace module name to "npm:hono-kv-session"
app.use('*', SessionManager({
// Cookie's id
name: 'session_cookie', // Default: 'id'
// Secret for Hono's signed cookies
secret: 'Strong_Secret_123', // Default: null
// Session TTL. Set for both KV and cookies. Minimum 60.
ttl: 60, // Default: 604800 (1 week)
// Update session TTL for each access.
renew: true, // Default: true
// Update session ID for each access.
regenerate: true, // Default: false
}))
secret
is secret of Hono's signed cookies (This feature has untested).Get session data
app.get('/', async (c) => {
const { value, key, name, status } = c.session;
return c.json({
username: value,
session_id: key, // Default: crypto.randomUUID()'s uuid
cookie_id: name,
status,
})
})
Deny Access
If you don’t use the denyAccess()
middleware, unauthorized sessions will not be denied and will be able to access the system.
By referencing c.session.status = true|false
, you can restrict access to specific routes or HTTP methods.
import { denyAccess } from 'hono-kv-session';
// If JSON
app.use('*', denyAccess({
type: 'json', // 'json' or 'html' or 'text'
status: 401, // status code
response: { status: false, message: 'Invalid session' }
}))
// If HTML
app.use('*', denyAccess({
type: 'html', // 'json' or 'html' or 'text'
status: 401, // status code
response: '<p>Invalid session</p>'
}));
Create session
app.post('/login', async (c) => {
// Extract client's username from FormData
const { user } = await c.req.parseBody()
// Create session
await createSession(c, user, {
secret: 'Strong_Secret_123' // If you are using signed cookie
})
return c.redirect('/')
})
Renewal session
app.get('/renew', async (c) => {
await renewSession(c)
return c.redirect('/')
})
Delete session
app.post('/logout', async (c) => {
await deleteSession(c)
return c.redirect('/')
})
session:<hostname>:<uuid>
and value
session:www.example.com:49b0b962-5b95-43c6-9e00-94ce1313d0ed
user01
id=49b0b962-5b95-43c6-9e00-94ce1313d0ed
c.session
c.session = {
session: 'user01' // KV value
key: `49b0b962-5b95-43c6-9e00-94ce1313d0ed` // KV key
name: 'id' // Cookie name
}
MIT