hono 集成 Better Auth

hono 集成 Better Auth

起始项目使用 syntax 团队成员 CJhono-open-api-starter。你可以去 GitHub 去下载源码和我一起做。

这里只演示使用 email 登录注册的功能,具体功能你可以去 Better Auth 文档 查看

为什么选择 Better Auth

我们看它官方的说法:

Better Auth 是一个与框架无关的 TypeScript 身份验证和授权框架。它提供了一套全面的开箱即用功能,并包含一个插件生态系统,简化了高级功能的添加。无论您需要双因素身份验证 (2FA)、多租户、多会话支持,还是像单点登录 (SSO) 这样的企业级功能,它都能让您专注于构建应用程序,而无需重复造轮子。

而且它在 GitHub 上很活跃,更新速度也蛮快。

Better Auth 的集成

对 hono-open-api-starter 项目的改造

我这里使用 postgresql 数据库,所以需要安装一些依赖

shell
pnpm add drizzle-orm pg dotenv
pnpm add -D drizzle-kit tsx @types/pg

相应的 db/index.ts 需要改造

db/index.tsts
import env from "@/helper/env";

import { drizzle } from "drizzle-orm/node-postgres";

import * as schema from "./schema/index";

import "dotenv/config";

const db = drizzle({
    connection: {
        connectionString: env.DATABASE_URL,
    },
    schema,
});

export { db };

drizzle.config.ts 文件改动

drizzle.config.tsts
import { defineConfig } from "drizzle-kit";

import env from "./src/helper/env";

import "dotenv/config";

export default defineConfig({
    out: "./src/db/migrations",
    schema: "./src/db/schema/**.ts",
    dialect: "postgresql",
    dbCredentials: {
        url: env.DATABASE_URL,
    },
});

安装 Better Auth

bash
pnpm add better-auth

配置 .env 文件

.env.env
BETTER_AUTH_SECRET= # 可以在文档中生成一个随机字符串使用
BETTER_AUTH_URL=http://localhost:9999 # 后端地址
DOMAIN=localhost # 项目启动域名
FRONT_END_URL=http://localhost:5173 # 前端地址

创建 auth.ts 文件

src/auth.tsts
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { admin, openAPI, organization } from "better-auth/plugins";

export const auth = betterAuth({
    database: drizzleAdapter(db, {
        // 这里我使用了 pg 数据库,所以这里填 pg
        provider: "pg",
    }),
    // openAPI 插件可以让我们在项目启动后使用 项目地址 + /api/auth/reference 访问其提供的 api
    // 这里我还启用了 admin 和 organization 插件
    plugins: [openAPI(), admin(), organization()],
})

生成相关 schema

shell
npx @better-auth/cli generate

生成的 schema 会在项目根目录中,我们将其移至 db/schema/ 文件夹中

使用 drizzle 相关命令来迁移数据库改动

pnpm drizzle-kit generate
pnpm drizzle-kit migrate

完善 auth.ts 文件

登录中间件,使用后可以在后续的请求中在 context 中访问 user 和 session 信息

AppOpenAPI 的类型做补充

解决 ts 类型报错的问题

lib/types.tsts
import type { auth } from "@/auth";
import type { OpenAPIHono, RouteConfig, RouteHandler } from "@hono/zod-openapi";

import type { PinoLogger } from "hono-pino";

export interface AppBindings {
    Variables: {
        logger: PinoLogger
        user: typeof auth.$Infer.Session.user | null
        session: typeof auth.$Infer.Session.session | null
    }
}

export type AppOpenAPI = OpenAPIHono<AppBindings>;

export type AppRouteHandler<R extends RouteConfig> = RouteHandler<R, AppBindings>;

在主路由中使用 Better Auth


前端使用

前端这里我使用 vite 搭建一个简单的项目来进行演示

shell
pnpm create vite --template vue-ts

安装 Better Auth

shell
pnpm add better-auth

使用

使用 Better Auth 提供的工具来访问它提供的接口是很方便的。我们需要在 /src/ 下创建一个 auth-client

src/lib/auth-client.tsts
import { adminClient, organizationClient } from "better-auth/client/plugins"
import { createAuthClient } from "better-auth/vue"

export const authClient = createAuthClient({
    baseURL: "http://localhost:9999",
    plugins: [
    // 这里如果后端有一些better-auth插件,这里也要引入对应的前端插件
        organizationClient(),
        adminClient()
    ]
})

创建好后,我们就可以在页面中使用它了


可能遇到的问题

跨域

因为是前后端分离项目,所以在使用时需要配置跨域相关内容,以上文章都有说明。跨域问题和 cookie 相关配置需要谨慎,最好限制指定域名跨域。

❌前后端不同源时,前端使用 better-auth 需要配置(不推荐)

这是我开始使用的一种方式,后端如果没有配置好跨域和 cookie 相关内容,会导致登录后使用 Better Auth clieht 相关的获取 session 的方法无法拿到对应的 session

ts
import { createAuthClient } from "better-auth/vue"
export const authClient = createAuthClient({
    /** The base URL of the server (optional if you're using the same domain) */
    baseURL: "http://localhost:9999",
    fetchOptions: {
        credentials: 'omit'
    }
})
使用 chatgpt 制作自己的小贴纸
shadcn-vue-admin 说明

评论区

评论加载中...