@pori15/elysia-auth-drizzle
v1.3.4
Published
Authentication plugin for Elysia using Drizzle ORM
Downloads
17
Maintainers
Readme
@pori15/elysia-auth-drizzle
一个为 Elysia 框架设计的强大认证插件,支持多种认证方式并与 Drizzle ORM 深度集成。
✨ 特性
- 🔐 多种认证方式:支持 HTTP Header、Cookie、查询参数三种认证方式
- 🎯 JWT 集成:内置 JWT 令牌生成、验证和管理
- 🗄️ Drizzle ORM 集成:与数据库用户和令牌表无缝集成
- 🛡️ Cookie 安全:支持 HMAC-SHA256 签名的安全 Cookie
- 🚦 灵活路由控制:可配置公共路由,无需认证即可访问
- 🔍 自定义验证:支持用户状态检查(如封禁、权限验证等)
- ⚡ 高性能:基于 Elysia 的高性能 Web 框架
- 📝 TypeScript 支持:完整的类型定义和类型安全
📦 安装
bun add @pori15/elysia-auth-drizzle🚀 快速开始
基本用法
import { Elysia } from 'elysia'
import { elysiaAuthDrizzlePlugin } from '@pori15/elysia-auth-drizzle'
import { db } from './db' // 你的 Drizzle 数据库实例
import { userSchema, tokenSchema } from './db/schema' // 你的数据库 schema
const app = new Elysia()
.use(
elysiaAuthDrizzlePlugin({
// JWT 密钥
jwtSecret: process.env.JWT_SECRET!,
// Cookie 签名密钥(可选)
cookieSecret: process.env.COOKIE_SECRET,
// 数据库配置
drizzle: {
db: db,
usersSchema: userSchema,
tokensSchema: tokenSchema,
},
// 认证方式配置(必需)
getTokenFrom: {
from: 'header', // 'header' | 'cookie' | 'query'
headerName: 'authorization', // 默认值
cookieName: 'authorization', // 默认值
queryName: 'access_token', // 默认值
},
// 公共路由配置(无需认证)
PublicUrlConfig: [
{ url: '/login', method: 'POST' },
{ url: '/register', method: 'POST' },
{ url: '/public/*', method: 'GET' },
],
})
)
.get('/protected', ({ isConnected, connectedUser }) => {
if (!isConnected) {
return { error: 'Unauthorized' }
}
return { user: connectedUser }
})
.listen(3000)完整示例
import { Elysia, t } from 'elysia'
import { elysiaAuthDrizzlePlugin, createUserToken } from '@pori15/elysia-auth-drizzle'
import { drizzle } from "drizzle-orm/bun-sql"
import { eq } from 'drizzle-orm'
import { userSchema, tokenSchema } from './db/schema'
const db = drizzle(process.env.DATABASE_URL!)
const app = new Elysia()
.use(
elysiaAuthDrizzlePlugin({
jwtSecret: 'your-jwt-secret-key',
cookieSecret: 'your-cookie-secret-key',
drizzle: {
db,
usersSchema: userSchema,
tokensSchema: tokenSchema,
},
getTokenFrom: {
from: 'header', // 从请求头获取token
headerName: 'authorization',
},
PublicUrlConfig: [
{ url: '/', method: '*' },
{ url: '/register', method: '*' },
{ url: '/login', method: '*' },
],
})
)
// ... 其他路由
.listen(3000)数据库 Schema 示例
import { pgTable, serial, text, timestamp, integer } from 'drizzle-orm/pg-core'
// 用户表
export const users = pgTable('users', {
id: serial('id').primaryKey(),
username: text('username').notNull().unique(),
password: text('password').notNull(),
createdAt: timestamp('created_at').defaultNow(),
updatedAt: timestamp('updated_at').defaultNow(),
})
// 令牌表(如果不使用 verifyAccessTokenOnlyInJWT)
export const tokens = pgTable('tokens', {
id: serial('id').primaryKey(),
ownerId: integer('owner_id').references(() => users.id),
accessToken: text('access_token').notNull(),
refreshToken: text('refresh_token'),
createdAt: timestamp('created_at').defaultNow(),
})🔧 配置选项
| 参数 | 类型 | 默认值 | 描述 |
| ---------------------------- | ----------------- | ------------------------------------------------------------------------- | ------------------------ |
| drizzle | object | 必需 | 数据库配置对象 |
| getTokenFrom | GetTokenOptions | 必需 | 令牌获取方式配置 |
| jwtSecret | string | undefined | JWT 签名密钥(可选) |
| cookieSecret | string | undefined | Cookie 签名密钥(可选) |
| PublicUrlConfig | UrlConfig[] | [{url: '*/login', method: 'POST'}, {url: '*/register', method: 'POST'}] | 公共路由配置 |
| verifyAccessTokenOnlyInJWT | boolean | false | 仅验证 JWT,不检查数据库 |
| userValidation | function | undefined | 自定义用户验证函数 |
GetTokenOptions 配置
interface GetTokenOptions {
from: 'header' | 'cookie' | 'query'
headerName?: string // 默认: 'authorization'
cookieName?: string // 默认: 'authorization'
queryName?: string // 默认: 'access_token'
}🔐 认证方式
1. Header 认证
// 配置
getTokenFrom: { from: 'header', headerName: 'authorization' }
// 请求示例
fetch('/api/protected', {
headers: {
'Authorization': 'Bearer your-jwt-token'
}
})2. Cookie 认证
// 配置
getTokenFrom: { from: 'cookie', cookieName: 'auth_token' }
cookieSecret: 'your-cookie-secret' // 启用 Cookie 签名
// Cookie 会自动包含在请求中3. 查询参数认证
// 配置
getTokenFrom: { from: 'query', queryName: 'token' }
// 请求示例
fetch('/api/protected?token=your-jwt-token')🛠️ 工具函数
插件还导出了一些有用的工具函数:
创建用户令牌
import { createUserToken } from '@pori15/elysia-auth-drizzle'
// 创建token生成器
const token = createUserToken({
db,
usersSchema: userSchema,
tokensSchema: tokenSchema
})
// 生成用户token
const tokenResult = await token(
userId, // 用户ID(字符串)
{
secret: 'your-jwt-secret-key',
accessTokenTime: '12h', // 访问令牌有效期
refreshTokenTime: '1d', // 刷新令牌有效期
}
)
// 返回结果包含:
// {
// accessToken: string,
// refreshToken: string,
// accessTokenTime: string,
// refreshTokenTime: string
// }其他工具函数
import {
signCookie,
unsignCookie,
getAccessTokenFromRequest,
checkTokenValidity,
currentUrlAndMethodIsAllowed
} from '@pori15/elysia-auth-drizzle'
// Cookie 签名
const signedCookie = await signCookie('value', 'secret')
// Cookie 验证
const originalValue = await unsignCookie(signedCookie, 'secret')
// 检查 URL 是否为公共路由
const isPublic = currentUrlAndMethodIsAllowed('/login', 'POST', publicRoutes)📝 高级用法
自定义用户验证
elysiaAuthDrizzlePlugin({
// ... 其他配置
userValidation: async (user) => {
// 检查用户是否被封禁
if (user.status === 'banned') {
throw new Error('User is banned')
}
// 检查用户权限
if (!user.isActive) {
throw new Error('User account is inactive')
}
}
})仅 JWT 验证模式
elysiaAuthDrizzlePlugin({
// ... 其他配置
verifyAccessTokenOnlyInJWT: true, // 不检查数据库中的令牌
// 在此模式下,tokensSchema 是可选的
})动态公共路由
const publicRoutes = [
{ url: '/api/health', method: 'GET' },
{ url: '/api/docs/*', method: 'GET' },
{ url: '/auth/*', method: 'POST' },
]
elysiaAuthDrizzlePlugin({
// ... 其他配置
PublicUrlConfig: publicRoutes
})