forked from 77media/video-flow
337 lines
6.8 KiB
Markdown
337 lines
6.8 KiB
Markdown
# Google OAuth2 API 接口文档
|
||
|
||
## 📋 概述
|
||
|
||
本文档为前端开发者提供 Google OAuth2 登录、注册和账户绑定相关的 API 接口说明。
|
||
|
||
**基础信息:**
|
||
|
||
- 基础路径:`/api/auth/google`
|
||
- 认证方式:Sa-Token(部分接口需要登录)
|
||
- 数据格式:JSON
|
||
- 字符编码:UTF-8
|
||
|
||
---
|
||
|
||
## 🔐 接口列表
|
||
|
||
### 1. 获取 Google 登录授权 URL
|
||
|
||
**接口地址:** `GET /api/auth/google/authorize`
|
||
|
||
**描述:** 生成 Google OAuth2 授权链接,用户访问此链接进行 Google 登录授权
|
||
|
||
**请求参数:** 无
|
||
|
||
**响应示例:**
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"authUrl": "https://accounts.google.com/oauth/authorize?client_id=847079918888-xxx&redirect_uri=http://localhost:8080/api/auth/google/callback&response_type=code&scope=openid+email+profile&state=uuid-string",
|
||
"state": "uuid-string",
|
||
"clientId": "847079918888-xxx"
|
||
}
|
||
}
|
||
```
|
||
|
||
**错误响应:**
|
||
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": "AUTHORIZATION_URL_GENERATION_FAILED",
|
||
"message": "生成授权链接失败"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2. Google 登录/注册
|
||
|
||
**接口地址:** `POST /api/auth/google/login`
|
||
|
||
**描述:** 通过 Google ID Token 进行用户登录或注册,支持新用户自动注册和邮箱冲突处理
|
||
|
||
**请求参数:**
|
||
|
||
```json
|
||
{
|
||
"idToken": "eyJhbGciOiJSUzI1NiIsImtpZCI6...", // Google ID Token(必填)
|
||
"action": "auto" // 操作类型:login | register | auto(可选,默认 auto)
|
||
}
|
||
```
|
||
|
||
**成功响应:**
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"token": "sa-token-string",
|
||
"userInfo": {
|
||
"userId": "user-123",
|
||
"userName": "user@gmail.com",
|
||
"name": "张三",
|
||
"email": "user@gmail.com",
|
||
"authType": "GOOGLE",
|
||
"url": "https://lh3.googleusercontent.com/...",
|
||
"isNewUser": false
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**邮箱冲突响应(HTTP 409):**
|
||
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": "EMAIL_ALREADY_EXISTS",
|
||
"message": "该邮箱已被其他账户使用,是否绑定 Google 账户?",
|
||
"data": {
|
||
"bindToken": "temporary-bind-token",
|
||
"existingUser": {
|
||
"email": "user@gmail.com",
|
||
"authType": "LOCAL"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**其他错误响应:**
|
||
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": "INVALID_GOOGLE_TOKEN",
|
||
"message": "Google Token 验证失败"
|
||
}
|
||
```
|
||
|
||
**错误码说明:**
|
||
|
||
- `INVALID_GOOGLE_TOKEN`: Google Token 无效或过期
|
||
- `EMAIL_ALREADY_EXISTS`: 邮箱已被其他账户使用
|
||
- `USER_NOT_FOUND`: 用户不存在(仅当 action=login 时)
|
||
- `REGISTRATION_FAILED`: 用户注册失败
|
||
- `GOOGLE_LOGIN_FAILED`: 登录处理失败
|
||
|
||
---
|
||
|
||
### 3. Google 账户绑定
|
||
|
||
**接口地址:** `POST /api/auth/google/bind`
|
||
|
||
**描述:** 将 Google 账户绑定到当前登录的用户账户
|
||
|
||
**认证要求:** 需要用户登录(Sa-Token)
|
||
|
||
**请求参数:**
|
||
|
||
```json
|
||
{
|
||
"idToken": "eyJhbGciOiJSUzI1NiIsImtpZCI6...", // Google ID Token(可选)
|
||
"confirm": true // 确认绑定(必填)
|
||
}
|
||
```
|
||
|
||
**成功响应:**
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"token": "new-sa-token",
|
||
"message": "Google 账户绑定成功"
|
||
}
|
||
}
|
||
```
|
||
|
||
**错误响应:**
|
||
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": "BINDING_FAILED",
|
||
"message": "账户绑定失败"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 4. 获取 Google 绑定状态
|
||
|
||
**接口地址:** `GET /api/auth/google/status`
|
||
|
||
**描述:** 查询当前用户的 Google 账户绑定状态
|
||
|
||
**认证要求:** 需要用户登录(Sa-Token)
|
||
|
||
**请求参数:** 无
|
||
|
||
**响应示例:**
|
||
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"isBound": true,
|
||
"userId": "user-123"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🔄 前端集成流程
|
||
|
||
### 方案一:使用 Google JavaScript SDK
|
||
|
||
1. **引入 Google SDK**
|
||
|
||
```html
|
||
<script src="https://accounts.google.com/gsi/client" async defer></script>
|
||
```
|
||
|
||
2. **初始化 Google 登录按钮**
|
||
|
||
```javascript
|
||
function initializeGoogleSignIn() {
|
||
google.accounts.id.initialize({
|
||
client_id:
|
||
'847079918888-o1nne8d3ij80dn20qurivo987pv07225.apps.googleusercontent.com',
|
||
callback: handleGoogleResponse,
|
||
})
|
||
|
||
google.accounts.id.renderButton(
|
||
document.getElementById('google-signin-button'),
|
||
{
|
||
theme: 'outline',
|
||
size: 'large',
|
||
text: 'signin_with',
|
||
locale: 'zh_CN',
|
||
}
|
||
)
|
||
}
|
||
```
|
||
|
||
3. **处理 Google 响应**
|
||
|
||
```javascript
|
||
async function handleGoogleResponse(response) {
|
||
try {
|
||
const result = await fetch('/api/auth/google/login', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
idToken: response.credential,
|
||
action: 'auto',
|
||
}),
|
||
})
|
||
|
||
const data = await result.json()
|
||
|
||
if (data.success) {
|
||
// 登录成功
|
||
localStorage.setItem('token', data.data.token)
|
||
console.log('用户信息:', data.data.userInfo)
|
||
// 跳转到主页面
|
||
} else if (result.status === 409) {
|
||
// 邮箱冲突,需要处理绑定逻辑
|
||
handleEmailConflict(data)
|
||
} else {
|
||
// 其他错误
|
||
console.error('登录失败:', data.message)
|
||
}
|
||
} catch (error) {
|
||
console.error('请求失败:', error)
|
||
}
|
||
}
|
||
```
|
||
|
||
### 方案二:使用授权 URL 重定向
|
||
|
||
1. **获取授权 URL**
|
||
|
||
```javascript
|
||
async function getGoogleAuthUrl() {
|
||
try {
|
||
const response = await fetch('/api/auth/google/authorize')
|
||
const data = await response.json()
|
||
|
||
if (data.success) {
|
||
// 保存 state 参数用于验证
|
||
sessionStorage.setItem('google_oauth_state', data.data.state)
|
||
// 重定向到 Google 授权页面
|
||
window.location.href = data.data.authUrl
|
||
}
|
||
} catch (error) {
|
||
console.error('获取授权 URL 失败:', error)
|
||
}
|
||
}
|
||
```
|
||
|
||
2. **处理回调(需要后端回调处理接口)**
|
||
|
||
```javascript
|
||
// 在回调页面处理授权码
|
||
function handleGoogleCallback() {
|
||
const urlParams = new URLSearchParams(window.location.search)
|
||
const code = urlParams.get('code')
|
||
const state = urlParams.get('state')
|
||
const savedState = sessionStorage.getItem('google_oauth_state')
|
||
|
||
if (state !== savedState) {
|
||
console.error('State 参数不匹配,可能存在 CSRF 攻击')
|
||
return
|
||
}
|
||
|
||
// 发送授权码到后端处理
|
||
// 这需要后端提供相应的回调处理接口
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🛡️ 安全注意事项
|
||
|
||
1. **Token 安全**
|
||
|
||
- 妥善保存用户的 Sa-Token
|
||
- 定期刷新 Token
|
||
- 在请求头中正确传递 Token
|
||
|
||
2. **CSRF 防护**
|
||
|
||
- 验证 state 参数
|
||
- 使用 HTTPS 协议
|
||
|
||
3. **错误处理**
|
||
|
||
- 妥善处理各种错误情况
|
||
- 不要在前端暴露敏感信息
|
||
|
||
4. **用户体验**
|
||
- 提供清晰的错误提示
|
||
- 处理网络异常情况
|
||
- 支持重试机制
|
||
|
||
---
|
||
|
||
## 📞 联系方式
|
||
|
||
如有疑问,请联系后端开发者:周梓鑫
|
||
|
||
**测试环境:** `http://localhost:8080`
|
||
**生产环境:** `https://your-production-domain.com`
|
||
|
||
---
|
||
|
||
## 📝 更新日志
|
||
|
||
- **2025-01-20**: 初始版本,支持 Google OAuth2 登录、注册和绑定功能
|