better auth worker on cloudflare

转载于:https://mp.weixin.qq.com/s/li5dsD1kXu6LFMT71bd3AQ

准备工作

  • 创建hono项目
shell 复制代码
lixiaobo@lixiaobodeMacBook-Pro cloudflare % npm create hono
> npx
> create-hono
create-hono version 0.19.4

✔ **Target directory** better-auth-cloudflare-demo

✔ **Which template do you want to use?** cloudflare-workers

✔ **Do you want to install project dependencies?** Yes

✔ **Which package manager do you want to use?** npm

✔ Cloning the template

✔ Installing project dependencies

🎉 **Copied project files**

Get started with: **cd better-auth-cloudflare-demo**
  • 安装依赖
shell 复制代码
npm install better-auth 
sql 复制代码
CREATE TABLE IF NOT EXISTS "user" (
	"id" text NOT NULL PRIMARY KEY,
	"name" text NOT NULL,
	"email" text NOT NULL UNIQUE,
	"emailVerified" integer NOT NULL,
	"image" text,
	"createdAt" date NOT NULL,
	"updatedAt" date NOT NULL
);
CREATE TABLE IF NOT EXISTS "session" (
	"id" text NOT NULL PRIMARY KEY,
	"userId" text NOT NULL,
	"token" text NOT NULL UNIQUE,
	"expiresAt" date NOT NULL,
	"ipAddress" text,
	"userAgent" text,
	"createdAt" date NOT NULL,
	"updatedAt" date NOT NULL,
	FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS "account" (
	"id" text NOT NULL PRIMARY KEY,
	"userId" text NOT NULL,
	"accountId" text NOT NULL,
	"providerId" text NOT NULL,
	"accessToken" text,
	"refreshToken" text,
	"accessTokenExpiresAt" date,
	"refreshTokenExpiresAt" date,
	"scope" text,
	"idToken" text,
	"password" text,
	"createdAt" date NOT NULL,
	"updatedAt" date NOT NULL,
	FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS "verification" (
	"id" text NOT NULL PRIMARY KEY,
	"identifier" text NOT NULL,
	"value" text NOT NULL,
	"expiresAt" date NOT NULL,
	"createdAt" date NOT NULL,
	"updatedAt" date NOT NULL
);
	```
* 创建本地数据库
	* 编辑wrangler.jsonc文件,添加d1_databases相关信息,本地运行的时候不存在"database_id",可以将其填为"00000000-0000-0000-0000-000000000000",线上运行的时候,按照真实填写
	```json
	"d1_databases": [  
	  {  
	    "binding": "DB",  
	    "database_name": "better-auth-cloudflare-demo",  
	    "database_id": ""  
	  }  
	]
	```
	* 将上面的sql语句保存在better-auth-cloudflare-demo.sql文件里面并执行如下命令
```shell
lixiaobo@lixiaobodeMacBook-Pro better-auth-cloudflare-demo % wrangler d1 execute better-auth-cloudflare-demo --local --file=better-auth-cloudflare-demo.sql
▲ [WARNING] **Proxy environment variables detected. We'll use your proxy for fetch requests.**
 ⛅️ wrangler 4.106.0
────────────────────
**Resource location:** local 
Use --remote if you want to access the remote instance.
🌀 Executing on local database better-auth-cloudflare-demo () from .wrangler/state/v3/d1:
🌀 To execute on your remote database, add a --remote flag to your wrangler command.
🚣 4 commands executed successfully.
	```
	* 查看数据库是否生成成功
		* npx localflare
		* webstrom
		* wrangler
		```shell
lixiaobo@lixiaobodeMacBook-Pro better-auth-cloudflare-demo % npx wrangler d1 execute DB --local --command="SELECT name FROM sqlite_master WHERE type='table';"
▲ [WARNING] **Proxy environment variables detected. We'll use your proxy for fetch requests.**
 ⛅️ wrangler 4.110.0
────────────────────
**Resource location:** local 
Use --remote if you want to access the remote instance.
🌀 Executing on local database DB () from .wrangler/state/v3/d1:
🌀 To execute on your remote database, add a --remote flag to your wrangler command.
🚣 1 command executed successfully.
┌──────────────┐
│ name         │
├──────────────┤
│ user         │
├──────────────┤
│ session      │
├──────────────┤
│ account      │
├──────────────┤
│ verification │
├──────────────┤
│ _cf_METADATA
  • 生成worker-configuration.d.ts
shell 复制代码
wrangler types

编写代码

  • src/lib/auth.ts
ts 复制代码
import {betterAuth} from "better-auth"  
  
export const createAuth = (env: Cloudflare.Env)=> betterAuth(  
    {  
        database: env.DB,  
        emailAndPassword: {  
            enabled: true,  
        },  
        secrets: [  
            { version: 1, value: env.SECRET_KEY_V1 },  
        ],  
        basePath: "/api/auth",  
        baseURL: {  
            allowedHosts: [  
                "localhost:*",  
            ],  
            protocol: "auto",  
        },  
    }  
);  
  
export type AuthInstance = ReturnType<typeof createAuth>;  
export type SessionUser = AuthInstance["$Infer"]["Session"]["user"];
  • 创建路由src/routes/user.ts
ts 复制代码
import {Hono} from 'hono'  
import {createAuth, SessionUser} from "../lib/auth";   
export const authRouter = new Hono<{Bindings: Cloudflare.Env, Variables: {user?:SessionUser}}>();  
export const AuthRouterPrefix = "/api/auth";  
// GET/POST /user/auth/*  
authRouter.all("/*", (c) => {  
    const auth = createAuth(c.env);  
    return auth.handler(c.req.raw);  
});  
  
// middleware: /user/*  
authRouter.use("/*", async (c, next) => {  
    const auth = createAuth(c.env);  
    const session = await auth.api.getSession({ headers: c.req.raw.headers });  
    c.set("user", session?.user);  
    await next();  
});  
  
// GET /api/me  
authRouter.get("/me", async (c) => {  
    if (!c.get("user")) {  
        return c.json({ error: "unauthorized" }, 401);  
    }  
    return c.json(c.get("user")!);  
});
  • src/index.ts
ts 复制代码
import { Hono } from 'hono'  
import {createAuth, SessionUser} from "./lib/auth";  
import {authRouter, AuthRouterPrefix} from "./routes/auth"  
  
const app = new Hono<{Bindings: Cloudflare.Env, Variables: {user?:SessionUser}}>()  
  
app.route(AuthRouterPrefix, authRouter);  
  
console.log("=== 当前可用的 API 端点列表 ===");  
app.routes.forEach(r => console.log(`[${r.method}]`.padEnd(8) + r.path));  
console.log("===============================");  
  
export default app

运行和测试

本地

运行

复制代码
```shell
wrangler dev
```

测试

  • 注册
shell 复制代码
lixiaobo@lixiaobodeMacBook-Pro better-auth-cloudflare-demo %    curl -X POST http://localhost:8787/api/auth/sign-up/email \
    -H 'Content-Type: application/json' \
    -d '{"email":"test@example.com","password":"12345678","name":"test"}'
{"token":"OS57FCQgo9n3maerb7kKoXfD2RNwGBDK","user":{"name":"test","email":"test@example.com","emailVerified":false,"image":null,"createdAt":"2026-07-10T11:10:23.856Z","updatedAt":"2026-07-10T11:10:23.856Z","id":"cvdFAOWgxn6PMd3WD51pMUQoaDW6iw2F"}}
  • 登录
shell 复制代码
lixiaobo@lixiaobodeMacBook-Pro better-auth-cloudflare-demo %    curl -sS \
    -X POST http://localhost:8787/api/auth/sign-in/email \
    -H 'Content-Type: application/json' \
    -d '{"email":"test@example.com","password":"12345678"}'
{"redirect":false,"token":"Var3ENBaJGZj4VQrpNzwta1cTtbxbUna","user":{"name":"test","email":"test@example.com","emailVerified":false,"image":null,"createdAt":"2026-07-10T11:10:23.856Z","updatedAt":"2026-07-10T11:10:23.856Z","id":"cvdFAOWgxn6PMd3WD51pMUQoaDW6iw2F"}}
  • 错误密码登录
shell 复制代码
lixiaobo@lixiaobodeMacBook-Pro better-auth-cloudflare-demo % curl -sS \
    -X POST http://localhost:8787/api/auth/sign-in/email \
    -H 'Content-Type: application/json' \
    -d '{"email":"test@example.com","password":"password123"}'
{"message":"Invalid email or password","code":"INVALID_EMAIL_OR_PASSWORD"}
  • 不存在的用户登录
shell 复制代码
lixiaobo@lixiaobodeMacBook-Pro better-auth-cloudflare-demo % curl -sS \
    -X POST http://localhost:8787/api/auth/sign-in/email \
    -H 'Content-Type: application/json' \
    -d '{"email":"nobody@example.com","password":"password123"}'
{"message":"Invalid email or password","code":"INVALID_EMAIL_OR_PASSWORD"

cloudflare运行

生成线上数据库

  • 创建数据库
shell 复制代码
lixiaobo@lixiaobodeMacBook-Pro better-auth-cloudflare-demo % wrangler d1 create better-auth-cloudflare-demo
▲ [WARNING] **Proxy environment variables detected. We'll use your proxy for fetch requests.**
 ⛅️ wrangler 4.106.0 (update available 4.110.0)
───────────────────────────────────────────────
✅ Successfully created DB 'better-auth-cloudflare-demo' in region WNAM
Created your new D1 database.
To access your new D1 Database in your Worker, add the following snippet to your configuration file:
{
  "d1_databases": [
    {
      "binding": "better_auth_cloudflare_demo",
      "database_name": "better-auth-cloudflare-demo",
      "database_id": "25b30dd3-b35d-45fa-9fa9-7c2af8240024"
    }
  ]
}
✔ **Would you like Wrangler to add it on your behalf?** ... yes
✔ **What binding name would you like to use?** ... better_auth_cloudflare_demo
✔ **For local dev, do you want to connect to the remote resource instead of a local resource?** ... yes
  • 将返回d1_databases信息,贴到wrangler.jsonc文件对应位置(默认应该会自动更新wrangler.jsonc,无须手动粘贴)
  • 创建表
shell 复制代码
lixiaobo@lixiaobodeMacBook-Pro better-auth-cloudflare-demo % wrangler d1 execute better-auth-cloudflare-demo --remote --file=./better-auth-cloudflare-demo.sql
▲ [WARNING] **Proxy environment variables detected. We'll use your proxy for fetch requests.**
 ⛅️ wrangler 4.106.0 (update available 4.110.0)
───────────────────────────────────────────────
**Resource location:** remote 
✔ **⚠️ This process may take some time, during which your D1 database will be unavailable to serve queries.**
  **Ok to proceed?** ... yes
🌀 Executing on remote database better-auth-cloudflare-demo (25b30dd3-b35d-45fa-9fa9-7c2af8240024):
🌀 To execute on your local development database, remove the --remote flag from your wrangler command.
Note: if the execution fails to complete, your DB will return to its original state and you can safely retry.
├ 🌀 Uploading 25b30dd3-b35d-45fa-9fa9-7c2af8240024.f838ba309bc50ebd.sql
│ 🌀 Uploading complete.
│
🌀 Starting import...
🌀 Processed 4 queries.
🚣 Executed 4 queries in 5.36ms (4 rows read, 14 rows written)
   Database is currently at bookmark 00000001-00000006-000050a4-51499d332507084e452c9586ed6634a2.
┌───────────────────────┬───────────┬──────────────┬───────────────────┐
│Total queries executed │ Rows read │ Rows written │ Database size (MB)│
├───────────────────────┼───────────┼──────────────┼───────────────────┤
│4                      │ 4         │ 14           │ 0.05              │
└───────────────────────┴───────────┴──────────────┴───────────────────┘

发布到线上,也可以使用自己的域名

shell 复制代码
lixiaobo@lixiaobodeMacBook-Pro better-auth-cloudflare-demo % wrangler deploy
▲ [WARNING] **Proxy environment variables detected. We'll use your proxy for fetch requests.**
 ⛅️ wrangler 4.106.0 (update available 4.110.0)
───────────────────────────────────────────────
Total Upload: 1759.21 KiB / gzip: 304.34 KiB
Worker Startup Time: 47 ms
Your Worker has access to the following bindings:
Binding                                                            Resource        
env.better_auth_cloudflare_demo (better-auth-cloudflare-demo)      D1 Database     
env.BETTER_AUTH_URL ("localhost")                                  Environment Variable      
Uploaded better-auth-cloudflare-demo (5.12 sec)
Deployed better-auth-cloudflare-demo triggers (1.95 sec)
  https://better-auth-cloudflare-demo.shakingwaves.workers.dev
Current Version ID: 2fb6c9de-4448-4954-9209-81ab9402e908
shell 复制代码
lixiaobo@lixiaobodeMacBook-Pro better-auth-cloudflare-demo % wrangler secret put SECRET_KEY_V1
▲ [WARNING] **Proxy environment variables detected. We'll use your proxy for fetch requests.**
 ⛅️ wrangler 4.106.0 (update available 4.110.0)
───────────────────────────────────────────────
✔ **Enter a secret value:** ... ********************************
🌀 Creating the secret for the Worker "better-auth-cloudflare-demo" 
✨ Success! Uploaded secret SECRET_KEY_V1
  • 测试,以此类推
shell 复制代码
lixiaobo@lixiaobodeMacBook-Pro better-auth-cloudflare-demo %    curl -X POST https://better-auth-cloudflare-demo.shakingwaves.workers.dev/api/auth/sign-up/email -H 'Content-Type: application/json' -d '{"email":"test@example.com","password":"12345678","name":"test"}'
{"token":"IBHF3ATPz4akhtFc05AqXgevqpkvq4Vn","user":{"name":"test","email":"test@example.com","emailVerified":false,"image":null,"createdAt":"2026-07-10T12:05:30.596Z","updatedAt":"2026-07-10T12:05:30.596Z","id":"tDVU8UApXsLcm8OZqeXJ6VtH3PZu1ena"}}
 curl -sS -X POST https://better-auth-cloudflare-demo.shakingwaves.workers.dev/api/auth/sign-in/email -H 'Content-Type: application/json' -d '{"email":"test@example.com","password":"12345678"}'
{"redirect":false,"token":"nZNqQpSCzDWFwwJ1gCaokeYAgM5uxWOa","user":{"name":"test","email":"test@example.com","emailVerified":false,"image":null,"createdAt":"2026-07-10T12:05:30.596Z","updatedAt":"2026-07-10T12:05:30.596Z","id":"tDVU8UApXsLcm8OZqeXJ6VtH3PZu1ena"}}
相关推荐
JaydenAI14 小时前
[TypeScript学习笔记-11]创建一个极简的monorepo项目
typescript·monorepo
濮水大叔15 小时前
舒服了,CabloyJS 的 AI Spec 驱动开发会自动生成甘特图和燃尽图
typescript·node.js·vibecoding
DreamLife☼3 天前
Agent开发环境搭建完全指南
python·docker·typescript·node·工业知识点
請你喝杯Java3 天前
网站部署平台怎么选:Vercel、Cloudflare、ChatGPT Sites 的区别、费用与国内访问
chatgpt·cloudflare·vercel
码艺-Alimjan3 天前
Tauri 2.x + Vue 3 桌面应用开发实战:从踩坑到完美落地
前端·javascript·vue.js·rust·typescript·go
大模型丫丫3 天前
用 TypeScript、NestJS 和 LangGraph 搭建一个可控的 AI Agent
javascript·人工智能·typescript
shmily麻瓜小菜鸡3 天前
JavaScript / TypeScript 易踩坑知识点 —— 异步编程类
开发语言·javascript·typescript
妙码生花4 天前
使用git更新ai-go-admin框架
前端·人工智能·git·golang·typescript·php