|
| 1 | +# iOS 应用网页登录集成指南 |
| 2 | + |
| 3 | +本文档旨在为 Web 开发团队提供与 iOS 端集成的详细说明,以实现通过 `ASWebAuthenticationSession` 进行的用户认证流程。 |
| 4 | + |
| 5 | +## 1. 认证流程概述 |
| 6 | + |
| 7 | +当 iOS 用户点击“通过网页登录”按钮时,应用会打开一个安全的应用内浏览器(由 `ASWebAuthenticationSession` 提供),并加载您指定的网页。用户在该网页上完成认证后,网页服务器需要将认证凭据(例如 Token)通过特定的 URL Scheme 回传给 iOS 应用。iOS 应用会拦截这个 URL,解析出凭据,并完成登录。 |
| 8 | + |
| 9 | +**核心流程**: |
| 10 | + |
| 11 | +1. iOS App 打开 `https://rote.ink/login?type=ioslogin`。 |
| 12 | +2. 用户在网页上完成登录操作(例如,输入用户名/密码,或通过第三方 OAuth 登录)。 |
| 13 | +3. Web 服务器验证成功后,**必须通过 HTTP 302 重定向** 到一个特定的 URL,该 URL 使用 iOS App 的自定义 Scheme `rote://`。 |
| 14 | +4. iOS App 监听到这个重定向,关闭浏览器,并从 URL 中提取 Token。 |
| 15 | + |
| 16 | +--- |
| 17 | + |
| 18 | +## 2. Web 端需要实现的关键步骤 |
| 19 | + |
| 20 | +### 步骤 1:创建登录入口页面 |
| 21 | + |
| 22 | +您需要确保以下 URL 是一个有效的、可供用户登录的页面: |
| 23 | + |
| 24 | +``` |
| 25 | +https://rote.ink/login?type=ioslogin |
| 26 | +``` |
| 27 | + |
| 28 | +iOS 应用会直接打开这个地址。您可以利用 `type=ioslogin` 这个查询参数来为来自 App 的请求展示特定的 UI(例如,隐藏“注册”按钮或导航栏)。 |
| 29 | + |
| 30 | +### 步骤 2:处理用户认证 |
| 31 | + |
| 32 | +用户在此页面上进行的所有认证操作(如表单提交、与第三方 OAuth 提供商交互等)均由您的服务器处理。这部分是标准的 Web 认证流程。 |
| 33 | + |
| 34 | +### 步骤 3:成功后的重定向(最关键的一步) |
| 35 | + |
| 36 | +当用户在您的服务器上成功认证后,服务器 **必须** 生成一个认证 Token (例如 JWT),然后构造一个回调 URL,并执行 **HTTP 302 重定向**。 |
| 37 | + |
| 38 | +**回调 URL 的格式必须如下**: |
| 39 | + |
| 40 | +``` |
| 41 | +rote://callback?token=YOUR_GENERATED_TOKEN |
| 42 | +``` |
| 43 | + |
| 44 | +**URL 构成详解**: |
| 45 | + |
| 46 | +- **Scheme**: `rote://` |
| 47 | + - 这是在 iOS 应用中预先定义好的,用于唤醒应用的协议。**必须**是这个值。 |
| 48 | +- **Host**: `callback` |
| 49 | + - 这部分可以自定义(例如 `auth`, `login-success` 等),但建议使用 `callback`。iOS 端目前没有严格校验 Host,但会解析整个 URL。 |
| 50 | +- **Query Parameter**: `?token=YOUR_GENERATED_TOKEN` |
| 51 | + - 这是最重要的部分。iOS 应用会专门查找名为 `token` 的查询参数来获取认证凭据。**参数名必须是 `token`**。 |
| 52 | + - `YOUR_GENERATED_TOKEN` 就是您服务器生成的实际用户 Token。 |
| 53 | + |
| 54 | +**服务器端实现示例 (使用 Express.js)**: |
| 55 | + |
| 56 | +```javascript |
| 57 | +const express = require("express"); |
| 58 | +const app = express(); |
| 59 | + |
| 60 | +// 伪代码:处理登录请求的路由 |
| 61 | +app.post("/login-handler", (req, res) => { |
| 62 | + // 1. 验证用户凭据 (req.body.username, req.body.password) |
| 63 | + const userIsValid = validateUser(req.body); |
| 64 | + |
| 65 | + if (userIsValid) { |
| 66 | + // 2. 如果验证成功,生成 Token |
| 67 | + const jwtToken = generateJwtForUser(req.body.username); |
| 68 | + |
| 69 | + // 3. 构造回调 URL |
| 70 | + const callbackUrl = `rote://callback?token=${jwtToken}`; |
| 71 | + |
| 72 | + // 4. 执行重定向 |
| 73 | + res.redirect(callbackUrl); |
| 74 | + } else { |
| 75 | + // 处理登录失败的情况 |
| 76 | + res.status(401).send("Authentication failed"); |
| 77 | + } |
| 78 | +}); |
| 79 | + |
| 80 | +// ... 其他代码 ... |
| 81 | +``` |
| 82 | + |
| 83 | +--- |
| 84 | + |
| 85 | +## 3. 流程总结 |
| 86 | + |
| 87 | +| 步骤 | 操作方 | 描述 | |
| 88 | +| :--- | :--------- | :------------------------------------------------------------------------------------------------------------- | |
| 89 | +| 1 | iOS App | 用户点击登录,打开 `https://rote.ink/login?type=ioslogin` | |
| 90 | +| 2 | 用户 | 在网页上输入凭据,点击登录 | |
| 91 | +| 3 | Web Server | 验证用户凭据,生成 Token | |
| 92 | +| 4 | Web Server | **关键**:返回 HTTP 302 响应,`Location` 头指向 `rote://callback?token=...` | |
| 93 | +| 5 | iOS App | `ASWebAuthenticationSession` 自动拦截重定向,关闭浏览器,将回调 URL `rote://callback?token=...` 传递给应用代码 | |
| 94 | +| 6 | iOS App | 解析 URL,提取 `token` 参数,保存 Token 并完成登录 | |
| 95 | + |
| 96 | +请确保 Web 端的实现在用户成功登录后,严格按照上述格式执行重定向。这是整个认证流程能够闭环的关键。 |
0 commit comments