xiaso-flnxi-website/AUTH_INTEGRATION_GUIDE.md
Your Name b1eab32c75 初始提交: FLNXI电商素材系统官方网站
- Next.js 项目框架
- 完整的认证系统集成
- 数据库配置和部署脚本
- 产品价格体系和文档
- Docker 部署配置
2025-12-13 21:38:32 +08:00

531 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# NextAuth.js (Auth.js) 集成指南
## 📋 方案介绍
**NextAuth.js** 是最流行的 Next.js 认证解决方案,完全开源免费。
### 核心优势
- ✅ **5分钟集成** - 超级简单
- ✅ **完全免费** - 无用户数限制
- ✅ **多种登录方式** - 邮箱、Google、GitHub、微信等
- ✅ **安全可靠** - OAuth 2.0 标准
- ✅ **完美集成** - 专为 Next.js 设计
---
## 🚀 快速集成步骤
### 第一步:安装依赖
```bash
cd /Users/lanmu/Desktop/xiaso
npm install next-auth@latest
```
### 第二步:配置环境变量
创建 `.env.local` 文件:
```env
# NextAuth 密钥(必须)
NEXTAUTH_SECRET=your-secret-key-here-replace-with-random-string
NEXTAUTH_URL=https://scs.flnxi.com
# Google OAuth(可选)
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
# GitHub OAuth(可选)
GITHUB_ID=your-github-client-id
GITHUB_SECRET=your-github-client-secret
```
生成密钥:
```bash
openssl rand -base64 32
```
### 第三步:创建 Auth API 路由
创建文件:`app/api/auth/[...nextauth]/route.ts`
```typescript
import NextAuth from "next-auth"
import GoogleProvider from "next-auth/providers/google"
import GitHubProvider from "next-auth/providers/github"
import CredentialsProvider from "next-auth/providers/credentials"
const handler = NextAuth({
providers: [
// 邮箱密码登录
CredentialsProvider({
name: 'Credentials',
credentials: {
email: { label: "邮箱", type: "email", placeholder: "user@example.com" },
password: { label: "密码", type: "password" }
},
async authorize(credentials, req) {
// 这里添加您的用户验证逻辑
// 例如:从数据库查询用户
const user = { id: "1", name: "用户", email: credentials?.email }
if (user) {
return user
}
return null
}
}),
// Google 登录(需要配置 OAuth)
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
}),
// GitHub 登录(需要配置 OAuth)
GitHubProvider({
clientId: process.env.GITHUB_ID!,
clientSecret: process.env.GITHUB_SECRET!,
}),
],
// 自定义登录页面
pages: {
signIn: '/auth/signin',
// signOut: '/auth/signout',
// error: '/auth/error',
},
// 回调函数
callbacks: {
async jwt({ token, user }) {
if (user) {
token.id = user.id
}
return token
},
async session({ session, token }) {
if (session.user) {
session.user.id = token.id as string
}
return session
},
},
// 会话策略
session: {
strategy: "jwt",
maxAge: 30 * 24 * 60 * 60, // 30 天
},
})
export { handler as GET, handler as POST }
```
### 第四步:创建登录页面
创建文件:`app/auth/signin/page.tsx`
```typescript
'use client'
import { signIn } from 'next-auth/react'
import { useState } from 'react'
import { Mail, Lock, Chrome, Github } from 'lucide-react'
export default function SignInPage() {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [loading, setLoading] = useState(false)
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
setLoading(true)
await signIn('credentials', {
email,
password,
callbackUrl: '/',
})
setLoading(false)
}
return (
<div className="min-h-screen bg-gradient-to-b from-apple-gray-50 to-white flex items-center justify-center px-4">
<div className="max-w-md w-full">
{/* Logo */}
<div className="text-center mb-8">
<h1 className="text-3xl font-bold text-apple-gray-900 mb-2">
登录 FLNXI
</h1>
<p className="text-apple-gray-600">
欢迎回来,请登录您的账户
</p>
</div>
{/* 登录卡片 */}
<div className="bg-white rounded-2xl apple-shadow-lg p-8">
{/* 邮箱密码登录 */}
<form onSubmit={handleSubmit} className="space-y-4 mb-6">
<div>
<label className="block text-sm font-medium text-apple-gray-700 mb-2">
邮箱地址
</label>
<div className="relative">
<Mail className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-apple-gray-400" />
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
className="w-full pl-10 pr-4 py-3 border border-apple-gray-200 rounded-xl focus:ring-2 focus:ring-apple-blue focus:border-transparent outline-none"
placeholder="your@email.com"
required
/>
</div>
</div>
<div>
<label className="block text-sm font-medium text-apple-gray-700 mb-2">
密码
</label>
<div className="relative">
<Lock className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-apple-gray-400" />
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="w-full pl-10 pr-4 py-3 border border-apple-gray-200 rounded-xl focus:ring-2 focus:ring-apple-blue focus:border-transparent outline-none"
placeholder="••••••••"
required
/>
</div>
</div>
<button
type="submit"
disabled={loading}
className="w-full py-3 bg-gradient-to-r from-apple-blue to-blue-600 text-white font-semibold rounded-xl button-hover apple-shadow disabled:opacity-50"
>
{loading ? '登录中...' : '登录'}
</button>
</form>
{/* 分割线 */}
<div className="relative my-6">
<div className="absolute inset-0 flex items-center">
<div className="w-full border-t border-apple-gray-200" />
</div>
<div className="relative flex justify-center text-sm">
<span className="px-4 bg-white text-apple-gray-500">
或使用第三方登录
</span>
</div>
</div>
{/* 第三方登录 */}
<div className="space-y-3">
<button
onClick={() => signIn('google', { callbackUrl: '/' })}
className="w-full flex items-center justify-center space-x-3 py-3 border-2 border-apple-gray-200 rounded-xl hover:bg-apple-gray-50 transition-all font-medium"
>
<Chrome className="w-5 h-5 text-red-500" />
<span>使用 Google 登录</span>
</button>
<button
onClick={() => signIn('github', { callbackUrl: '/' })}
className="w-full flex items-center justify-center space-x-3 py-3 border-2 border-apple-gray-200 rounded-xl hover:bg-apple-gray-50 transition-all font-medium"
>
<Github className="w-5 h-5" />
<span>使用 GitHub 登录</span>
</button>
</div>
{/* 底部链接 */}
<div className="mt-6 text-center text-sm text-apple-gray-600">
还没有账户?
<a href="/auth/signup" className="text-apple-blue hover:underline ml-1">
立即注册
</a>
</div>
</div>
{/* 返回首页 */}
<div className="text-center mt-6">
<a href="/" className="text-apple-gray-600 hover:text-apple-blue transition-colors">
← 返回首页
</a>
</div>
</div>
</div>
)
}
```
### 第五步:添加 Session Provider
修改 `app/layout.tsx`:
```typescript
import { getServerSession } from "next-auth/next"
import SessionProvider from '@/components/SessionProvider'
export default async function RootLayout({
children,
}: {
children: React.ReactNode
}) {
const session = await getServerSession()
return (
<html lang="zh-CN">
<body>
<SessionProvider session={session}>
{children}
</SessionProvider>
</body>
</html>
)
}
```
创建 `components/SessionProvider.tsx`:
```typescript
'use client'
import { SessionProvider as NextAuthSessionProvider } from 'next-auth/react'
export default function SessionProvider({
children,
session,
}: {
children: React.ReactNode
session: any
}) {
return (
<NextAuthSessionProvider session={session}>
{children}
</NextAuthSessionProvider>
)
}
```
### 第六步:在 Header 中添加登录按钮
修改 `components/Header.tsx`,添加登录状态:
```typescript
'use client'
import { useSession, signIn, signOut } from 'next-auth/react'
import { User, LogOut } from 'lucide-react'
export default function Header({ scrolled }: HeaderProps) {
const { data: session, status } = useSession()
return (
<header>
{/* ... 其他代码 ... */}
{/* 添加登录/用户信息 */}
<div className="flex items-center space-x-4">
{status === 'loading' ? (
<div className="w-8 h-8 rounded-full bg-apple-gray-200 animate-pulse" />
) : session ? (
// 已登录
<div className="flex items-center space-x-3">
<span className="text-sm text-apple-gray-700">
{session.user?.name || session.user?.email}
</span>
<button
onClick={() => signOut()}
className="flex items-center space-x-2 px-4 py-2 text-apple-gray-700 hover:text-apple-blue transition-colors"
>
<LogOut className="w-4 h-4" />
<span>退出</span>
</button>
</div>
) : (
// 未登录
<button
onClick={() => signIn()}
className="flex items-center space-x-2 px-5 py-2 bg-apple-blue text-white rounded-full text-sm font-medium button-hover apple-shadow"
>
<User className="w-4 h-4" />
<span>登录</span>
</button>
)}
</div>
</header>
)
}
```
---
## 🎨 高级功能
### 1. 添加注册页面
创建 `app/auth/signup/page.tsx`(类似登录页面)
### 2. 保护页面(需要登录才能访问)
```typescript
// app/dashboard/page.tsx
import { getServerSession } from "next-auth/next"
import { redirect } from "next/navigation"
export default async function DashboardPage() {
const session = await getServerSession()
if (!session) {
redirect('/auth/signin')
}
return <div>受保护的页面内容</div>
}
```
### 3. 添加微信登录
```bash
npm install next-auth-wechat
```
```typescript
// 在 [...nextauth]/route.ts 中添加
import WeChatProvider from "next-auth-wechat"
providers: [
WeChatProvider({
clientId: process.env.WECHAT_APP_ID!,
clientSecret: process.env.WECHAT_APP_SECRET!,
}),
]
```
---
## 📦 部署配置
### 1. 更新环境变量
在服务器上设置环境变量:
```bash
ssh root@45.249.208.118
# 编辑环境变量
cd /opt/flnxi-website
nano .env.local
```
添加:
```env
NEXTAUTH_SECRET=<生成的密钥>
NEXTAUTH_URL=https://scs.flnxi.com
```
### 2. 更新 Docker 配置
修改 `docker-compose.yml`:
```yaml
services:
web:
build:
context: .
dockerfile: Dockerfile
ports:
- "4782:3000"
environment:
- NODE_ENV=production
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
- NEXTAUTH_URL=${NEXTAUTH_URL}
env_file:
- .env.local
restart: unless-stopped
```
### 3. 重新构建部署
```bash
docker-compose down
docker-compose up -d --build
```
---
## 🔐 配置第三方登录
### Google OAuth 配置
1. 访问 [Google Cloud Console](https://console.cloud.google.com/)
2. 创建新项目
3. 启用 Google+ API
4. 创建 OAuth 2.0 凭据
5. 添加授权重定向 URI:`https://scs.flnxi.com/api/auth/callback/google`
### GitHub OAuth 配置
1. 访问 [GitHub Settings > Developer settings](https://github.com/settings/developers)
2. 创建 New OAuth App
3. 添加授权回调 URL:`https://scs.flnxi.com/api/auth/callback/github`
---
## 📊 功能对比
| 功能 | NextAuth.js | Clerk | Logto |
|------|-------------|-------|-------|
| 开源免费 | ✅ | ⚠️ 有限制 | ✅ |
| 集成难度 | 简单 | 超简单 | 中等 |
| 用户数限制 | 无限制 | 10k MAU | 无限制 |
| UI 自定义 | 完全自定义 | 有限 | 可自定义 |
| 中文支持 | 需自己实现 | 支持 | 原生支持 |
| 需要额外服务 | ❌ | ❌ | ✅ |
---
## ✅ 集成检查清单
- [ ] 安装 next-auth 依赖
- [ ] 创建 API 路由 `[...nextauth]/route.ts`
- [ ] 配置环境变量(NEXTAUTH_SECRET)
- [ ] 创建登录页面
- [ ] 添加 SessionProvider
- [ ] 更新 Header 组件
- [ ] 测试邮箱登录
- [ ] (可选)配置 Google OAuth
- [ ] (可选)配置 GitHub OAuth
- [ ] 部署到服务器
- [ ] 测试生产环境
---
## 🎯 推荐时间线
- **5分钟**:基础集成(邮箱登录)
- **+10分钟**:美化登录页面
- **+15分钟**:添加 Google/GitHub 登录
- **+10分钟**:测试和部署
**总计:40分钟完成完整集成**
---
## 📞 获取帮助
如果遇到问题:
1. 查看 [NextAuth.js 官方文档](https://next-auth.js.org/)
2. 搜索 [GitHub Issues](https://github.com/nextauthjs/next-auth/issues)
3. 加入 [Discord 社区](https://discord.gg/nextauth)
---
**准备好了吗?让我开始帮您集成!** 🚀