1. 移除NFC和蓝牙相关依赖、权限及功能代码,精简传输链路 2. 重构设备在线统计逻辑,使用后端7天活跃字段替代本地计算 3. 更新应用名称、权限说明和协议文档 4. 新增消息转发、缓存管理、医疗免责提示功能 5. 优化运势模块和字体管理文案,修复构建日志问题
391 lines
12 KiB
Markdown
391 lines
12 KiB
Markdown
# 闲言APP — OAuth 社交登录对接指南
|
||
|
||
> 创建时间: 2026-06-05
|
||
> 更新时间: 2026-06-05
|
||
> 版本: v1.0
|
||
> 状态: 待对接(前端按钮已用 TODO 隐藏)
|
||
> 关联文档: API_OAUTH_DOC.md
|
||
|
||
---
|
||
|
||
## 一、当前状态
|
||
|
||
| 组件 | 状态 | 说明 |
|
||
|------|------|------|
|
||
| 后端 Oauth.php 控制器 | ✅ 已完成 | 已上传服务器,接口测试通过 |
|
||
| 后端路由配置 | ✅ 已完成 | 6条OAuth路由已注册 |
|
||
| 数据表 tool_user_oauth | ✅ 已创建 | install接口已验证 |
|
||
| API文档 | ✅ 已完成 | docs/toolsapi/docs/API_OAUTH_DOC.md |
|
||
| Flutter OAuthService | ✅ 已完成 | lib/features/auth/services/oauth_service.dart |
|
||
| Flutter 登录页按钮 | ⏸️ TODO隐藏 | 待OAuth配置完成后启用 |
|
||
| 各平台OAuth配置 | ❌ 未配置 | 需要在各平台创建应用并获取凭据 |
|
||
| 服务器数据库配置 | ❌ 未写入 | 需要向 tool_oauth_config 表写入各平台凭据 |
|
||
|
||
**启用按钮位置**: `lib/features/auth/presentation/login_page.dart` 第530行,搜索 `TODO: [OAuth社交登录]`
|
||
|
||
---
|
||
|
||
## 二、GitHub 对接(推荐优先配置)
|
||
|
||
### 2.1 难度:⭐(最简单,无需审核)
|
||
|
||
### 2.2 前置条件
|
||
- GitHub 账号
|
||
|
||
### 2.3 操作步骤
|
||
|
||
1. 打开 https://github.com/settings/developers
|
||
2. 点击 **New OAuth App**
|
||
3. 填写信息:
|
||
|
||
| 字段 | 值 |
|
||
|------|-----|
|
||
| Application name | 闲言工具箱 |
|
||
| Homepage URL | https://tools.wktyl.com |
|
||
| Authorization callback URL | https://tools.wktyl.com/oauth/callback |
|
||
|
||
4. 点击 **Register application**
|
||
5. 记录 **Client ID**(页面直接显示)
|
||
6. 点击 **Generate a new client secret** → 记录 **Client Secret**(只显示一次!)
|
||
|
||
### 2.4 写入服务器
|
||
|
||
```sql
|
||
-- 确保 oauth_config 表存在
|
||
CREATE TABLE IF NOT EXISTS `tool_oauth_config` (
|
||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||
`platform` varchar(30) NOT NULL DEFAULT '',
|
||
`config` text NOT NULL,
|
||
`status` tinyint(1) NOT NULL DEFAULT 1,
|
||
`createtime` int(11) unsigned NOT NULL DEFAULT 0,
|
||
`updatetime` int(11) unsigned NOT NULL DEFAULT 0,
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_platform` (`platform`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||
|
||
-- 写入GitHub配置(替换为实际值)
|
||
INSERT INTO `tool_oauth_config` (`platform`, `config`, `status`, `createtime`, `updatetime`)
|
||
VALUES ('github', '{
|
||
"client_id": "你的GitHub Client ID",
|
||
"client_secret": "你的GitHub Client Secret",
|
||
"redirect_uri": "https://tools.wktyl.com/oauth/callback"
|
||
}', 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
|
||
```
|
||
|
||
### 2.5 Flutter端配置
|
||
|
||
GitHub登录使用浏览器OAuth流程(`flutter_web_auth`),需要配置:
|
||
|
||
**Android** — `android/app/src/main/AndroidManifest.xml` 添加:
|
||
```xml
|
||
<activity android:name="com.linusu.flutter_web_auth.CallbackActivity"
|
||
android:exported="true">
|
||
<intent-filter android:allowWebResizing="true">
|
||
<action android:name="android.intent.action.VIEW" />
|
||
<category android:name="android.intent.category.DEFAULT" />
|
||
<category android:name="android.intent.category.BROWSABLE" />
|
||
<data android:scheme="xianyan" />
|
||
</intent-filter>
|
||
</activity>
|
||
```
|
||
|
||
**iOS** — `ios/Runner/Info.plist` 添加:
|
||
```xml
|
||
<key>CFBundleURLTypes</key>
|
||
<array>
|
||
<dict>
|
||
<key>CFBundleTypeRole</key>
|
||
<string>Editor</string>
|
||
<key>CFBundleURLSchemes</key>
|
||
<array>
|
||
<string>xianyan</string>
|
||
</array>
|
||
</dict>
|
||
</array>
|
||
```
|
||
|
||
### 2.6 验证
|
||
|
||
```bash
|
||
curl -s "https://tools.wktyl.com/api/oauth/config?platform=github" | python3 -m json.tool
|
||
# 期望: configured: true
|
||
```
|
||
|
||
### 2.7 注意事项
|
||
- Client Secret 只在创建时显示一次,务必保存
|
||
- GitHub OAuth App 无审核流程,创建即可用
|
||
- 回调URL必须完全匹配,包括 http/https
|
||
- 可同时创建多个 OAuth App(如测试环境和生产环境)
|
||
|
||
---
|
||
|
||
## 三、Google 对接
|
||
|
||
### 3.1 难度:⭐⭐
|
||
|
||
### 3.2 前置条件
|
||
- Google 账号
|
||
- GCP 项目(免费创建)
|
||
|
||
### 3.3 操作步骤
|
||
|
||
#### 步骤1:创建GCP项目
|
||
|
||
1. 打开 https://console.cloud.google.com/
|
||
2. 顶部项目选择器 → **新建项目**
|
||
3. 项目名称:`闲言工具箱` → **创建**
|
||
|
||
#### 步骤2:配置OAuth同意屏幕
|
||
|
||
1. 左侧菜单 → **APIs & Services** → **OAuth consent screen**
|
||
2. 选择 **External** → **Create**
|
||
3. 填写:
|
||
|
||
| 字段 | 值 |
|
||
|------|-----|
|
||
| App name | 闲言工具箱 |
|
||
| User support email | 你的邮箱 |
|
||
| Developer contact email | 你的邮箱 |
|
||
|
||
4. Scopes 页面 → 添加:`email`、`profile`、`openid`
|
||
5. Test users → 添加你的 Gmail(未发布时仅测试用户可用)
|
||
6. 完成后点击 **Publish App** 发布(需Google审核1-3天)
|
||
|
||
#### 步骤3:创建3个OAuth凭据
|
||
|
||
**Android客户端:**
|
||
1. **Credentials** → **Create Credentials** → **OAuth client ID** → **Android**
|
||
2. Package name: `apps.xy.xianyan`
|
||
3. SHA-1: 从签名文件获取
|
||
```bash
|
||
# debug签名
|
||
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
|
||
# release签名
|
||
keytool -list -v -keystore 你的keystore文件 -alias 你的别名
|
||
```
|
||
|
||
**iOS客户端:**
|
||
1. **OAuth client ID** → **iOS**
|
||
2. Bundle ID: `apps.xy.xianyan`
|
||
|
||
**Web客户端(服务端用,最关键):**
|
||
1. **OAuth client ID** → **Web application**
|
||
2. Authorized redirect URIs: `https://tools.wktyl.com/oauth/callback`
|
||
3. 记录 **Client ID** 和 **Client Secret**
|
||
|
||
#### 步骤4:写入服务器
|
||
|
||
```sql
|
||
INSERT INTO `tool_oauth_config` (`platform`, `config`, `status`, `createtime`, `updatetime`)
|
||
VALUES ('google', '{
|
||
"client_id": "你的Web客户端Client ID.apps.googleusercontent.com",
|
||
"client_secret": "你的Web客户端Client Secret",
|
||
"redirect_uri": "https://tools.wktyl.com/oauth/callback"
|
||
}', 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
|
||
```
|
||
|
||
#### 步骤5:Flutter端配置
|
||
|
||
**Android** — `android/app/src/main/AndroidManifest.xml` 的 `<application>` 内:
|
||
```xml
|
||
<meta-data android:name="com.google.android.gms.client_id"
|
||
android:value="你的Web客户端Client ID" />
|
||
```
|
||
|
||
**iOS** — `ios/Runner/Info.plist`:
|
||
```xml
|
||
<key>CFBundleURLTypes</key>
|
||
<array>
|
||
<dict>
|
||
<key>CFBundleTypeRole</key>
|
||
<string>Editor</string>
|
||
<key>CFBundleURLSchemes</key>
|
||
<array>
|
||
<!-- 反转Client ID,如 com.googleusercontent.apps.123456-abc -->
|
||
<string>你的反转Client ID</string>
|
||
</array>
|
||
</dict>
|
||
</array>
|
||
```
|
||
|
||
#### 步骤6:验证
|
||
|
||
```bash
|
||
curl -s "https://tools.wktyl.com/api/oauth/config?platform=google" | python3 -m json.tool
|
||
# 期望: configured: true
|
||
```
|
||
|
||
### 3.4 注意事项
|
||
- Google登录完全免费,无调用次数限制
|
||
- 未发布状态仅测试用户可用,发布需审核
|
||
- Android端SHA-1必须与签名文件匹配,debug/release不同
|
||
- 3个Client ID各有用途:Android/iOS给客户端SDK,Web给服务端
|
||
- 写入数据库的是 **Web客户端** 的 Client ID 和 Client Secret
|
||
|
||
---
|
||
|
||
## 四、Apple 对接
|
||
|
||
### 4.1 难度:⭐⭐⭐
|
||
|
||
### 4.2 前置条件
|
||
- Apple 开发者账号($99/年)
|
||
- 仅 iOS 13+ / macOS 10.15+ 可用
|
||
|
||
### 4.3 操作步骤
|
||
|
||
#### 步骤1:开启App的Sign in with Apple能力
|
||
|
||
1. 打开 https://developer.apple.com/
|
||
2. **Certificates, Identifiers & Profiles** → **Identifiers**
|
||
3. 选择 App ID(`apps.xy.xianyan`)
|
||
4. 勾选 **Sign in with Apple** → 保存
|
||
|
||
#### 步骤2:创建Services ID(Web端验证用)
|
||
|
||
1. **Identifiers** → **Register a Services ID**
|
||
2. 填写:
|
||
- Identifier: `apps.xy.xianyan.service`
|
||
- 勾选 **Sign in with Apple**
|
||
- Configure:
|
||
- Primary App ID: 选择你的 App ID
|
||
- Domain: `tools.wktyl.com`
|
||
- Return URL: `https://tools.wktyl.com/oauth/callback`
|
||
|
||
#### 步骤3:创建API Key
|
||
|
||
1. **Keys** → **Create a Key**
|
||
2. 勾选 **Sign in with Apple**
|
||
3. 配置:选择你的 App ID
|
||
4. 下载 .p8 文件(只能下载一次!)
|
||
5. 记录 **Key ID** 和 **Team ID**(Account页面查看)
|
||
|
||
#### 步骤4:写入服务器
|
||
|
||
```sql
|
||
INSERT INTO `tool_oauth_config` (`platform`, `config`, `status`, `createtime`, `updatetime`)
|
||
VALUES ('apple', '{
|
||
"client_id": "apps.xy.xianyan.service",
|
||
"team_id": "你的TeamID",
|
||
"key_id": "你的KeyID",
|
||
"private_key": "-----BEGIN PRIVATE KEY-----\n你的p8文件内容\n-----END PRIVATE KEY-----",
|
||
"redirect_uri": "https://tools.wktyl.com/oauth/callback"
|
||
}', 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
|
||
```
|
||
|
||
#### 步骤5:Flutter端配置
|
||
|
||
**iOS** — Xcode中:
|
||
1. 打开 `ios/Runner.xcworkspace`
|
||
2. **Signing & Capabilities** → **+ Capability** → **Sign in with Apple**
|
||
|
||
或手动在 `ios/Runner/Info.plist` 添加:
|
||
```xml
|
||
<key>com.apple.developer.applesignin</key>
|
||
<array>
|
||
<string>Default</string>
|
||
</array>
|
||
```
|
||
|
||
**macOS** — 同样需要在 Xcode 中添加 Sign in with Apple 能力。
|
||
|
||
#### 步骤6:验证
|
||
|
||
```bash
|
||
curl -s "https://tools.wktyl.com/api/oauth/config?platform=apple" | python3 -m json.tool
|
||
# 期望: configured: true
|
||
```
|
||
|
||
### 4.4 注意事项
|
||
- Apple登录仅iOS 13+和macOS 10.15+可用,Android/Web不支持
|
||
- .p8文件只能下载一次,务必安全保存
|
||
- Apple不提供用户昵称和头像(仅首次授权时返回全名)
|
||
- Apple允许用户隐藏邮箱,此时返回的是Apple生成的中转邮箱
|
||
- 需要Apple开发者账号(付费$99/年),否则无法使用
|
||
|
||
---
|
||
|
||
## 五、启用前端按钮
|
||
|
||
配置完成后,在 `login_page.dart` 中搜索 `TODO: [OAuth社交登录]`,取消注释即可:
|
||
|
||
```dart
|
||
// 将注释代码取消注释,删除 TODO 行
|
||
// 第530行附近
|
||
```
|
||
|
||
同时需要确保 `pubspec.yaml` 中的依赖已安装:
|
||
```yaml
|
||
sign_in_with_apple: ^6.1.0 # Apple登录
|
||
google_sign_in: ^6.2.1 # Google登录
|
||
flutter_web_auth: ^0.6.0 # GitHub浏览器OAuth
|
||
```
|
||
|
||
运行 `flutter pub get` 安装依赖。
|
||
|
||
---
|
||
|
||
## 六、对接检查清单
|
||
|
||
| 检查项 | GitHub | Google | Apple |
|
||
|--------|--------|--------|-------|
|
||
| 平台账号 | ✅ | ✅ | ✅ |
|
||
| 创建OAuth应用 | ☐ | ☐ | ☐ |
|
||
| 获取Client ID | ☐ | ☐ | ☐ |
|
||
| 获取Client Secret | ☐ | ☐ | ☐ |
|
||
| 配置回调URL | ☐ | ☐ | ☐ |
|
||
| 写入服务器数据库 | ☐ | ☐ | ☐ |
|
||
| Flutter端平台配置 | ☐ | ☐ | ☐ |
|
||
| 接口验证configured:true | ☐ | ☐ | ☐ |
|
||
| 实际登录测试 | ☐ | ☐ | ☐ |
|
||
| 取消TODO隐藏按钮 | ☐ | ☐ | ☐ |
|
||
|
||
---
|
||
|
||
## 七、测试脚本
|
||
|
||
已提供测试脚本:`docs/toolsapi/scripts/test_oauth_api.py`
|
||
|
||
```bash
|
||
cd /Users/wushu/Documents/trae_projects/project/xianyan
|
||
python3 docs/toolsapi/scripts/test_oauth_api.py
|
||
```
|
||
|
||
当前测试结果(10/10通过):
|
||
- 安装数据表 ✅
|
||
- 获取OAuth配置(3个平台) ✅
|
||
- 无效参数拒绝 ✅
|
||
- 未登录操作拒绝 ✅
|
||
|
||
---
|
||
|
||
## 八、架构说明
|
||
|
||
### 后端
|
||
- 控制器: `application/api/controller/Oauth.php`
|
||
- 路由: `application/route.php` → `/api/oauth/*`
|
||
- 数据表: `tool_user_oauth`(绑定关系)、`tool_oauth_config`(平台配置)
|
||
- API文档: `docs/toolsapi/docs/API_OAUTH_DOC.md`
|
||
|
||
### 前端
|
||
- 服务层: `lib/features/auth/services/oauth_service.dart`
|
||
- 登录页: `lib/features/auth/presentation/login_page.dart`
|
||
- 翻译键: `auth.otherLoginMethods`(14种语言)
|
||
|
||
### 登录流程
|
||
```
|
||
客户端SDK获取授权码 → OAuthService._loginToServer() → POST /api/oauth/login
|
||
→ 服务端验证授权码 → 查找/创建用户 → 返回Token → 客户端保存Token
|
||
```
|
||
|
||
---
|
||
|
||
## 九、安全注意事项
|
||
|
||
1. **Client Secret 保密**:仅存于服务器数据库,不写入客户端代码
|
||
2. **HTTPS强制**:所有OAuth回调必须使用HTTPS
|
||
3. **频率限制**:登录接口30次/5分钟,绑定/解绑20次/小时
|
||
4. **Token安全**:OAuth access_token/refresh_token 加密存储于数据库
|
||
5. **账号关联**:同一openid只能绑定一个闲言账号,邮箱相同自动关联
|
||
6. **Apple隐私**:用户可选择隐藏邮箱,需处理中转邮箱场景
|