# Guideline 4.8：必须加 Apple 登录吗？

> App 用 Google 或 Facebook 登录时，还要提供一个能隐藏邮箱的同等登录方式，比如 Apple 登录。附例外、Expo 代码和账号删除。

原始页面：[Guideline 4.8：必须加 Apple 登录吗？](https://devoria.fr/zh-hans/blog/guideline-4-8-sign-in-with-apple)
作者：[Mehdi Azizi](https://devoria.fr/zh-hans/mehdi-azizi)
发布：2026-10-27
内容最后修订：2026-10-27


只要你的 App 用 Google、Facebook 或其他第三方登录来创建主账号，Guideline 4.8 就会生效。这时它要求你再提供一个同等的登录选项：只收集姓名和邮箱，允许用户隐藏邮箱，未经同意不会为了广告追踪用户。**从 2024 年 1 月起，这个选项不一定非得是“Sign in with Apple”，但 Apple 在拒审消息里点名的就是它。**

在我的 App 里，Solys 和 Nolera 都提供 Apple、Google 和邮箱登录。这篇指南从 Apple 现行的条文讲起，然后演示我怎么在一个接入 Supabase 的 Expo App 里加上 Apple 登录，以及它对账号删除有什么影响。想了解所有拒审原因的全貌，请看[Apple 为什么拒绝你的 App](https://devoria.fr/zh-hans/blog/apple-app-rejection-reasons-real-cases)。

## Guideline 4.8 Login Services 说了什么？

4.8 位于 [App Review Guidelines](https://developer.apple.com/app-store/review/guidelines/#login-services) 第 4 部分“Design”。它针对的是用“a third-party or social login service”来创建或验证主账号的 App：Facebook Login、Google Sign-In、Log in with X、LinkedIn、Amazon 或微信。这类 App 还必须“as an equivalent option”提供另一个登录服务，并满足三个条件。

| Apple 的条件       | 说白了                   |
| ------------------ | ------------------------ |
| 数据有限           | 只有姓名和邮箱，别无其他 |
| 可使用私密邮箱     | 用户可以隐藏邮箱         |
| 未经同意不用于广告 | 未经同意不做广告追踪     |

条文也定义了什么是主账号：用户在你的 App 里创建、用来识别身份、登录并使用你各项功能的账号。按这个定义，**一个只用来导入文件的 Google 按钮不会创建主账号**。4.8 针对的是进入你 App 的那个界面。

### 2024 年 1 月的变化

2024 年之前，规则要求用第三方登录创建主账号的 App 必须提供“Sign in with Apple”。[2024 年 1 月 25 日](https://developer.apple.com/news/?id=f1v8pyay)，Apple 放宽了这一点：你可以提供 Apple 登录，也可以提供一个同等的、保护隐私的服务。很多页面现在还写着相反的说法。[Expo 的文档](https://docs.expo.dev/versions/latest/sdk/apple-authentication/)仍然写着带第三方登录的 App 必须提供 Apple 登录。

实际上，[Apple 开发者论坛](https://developer.apple.com/forums/thread/765145)上公开的一条 4.8 拒审消息是这样结尾的：“Note that Sign in with Apple meets the requirements specified in guideline 4.8”。Apple 没有点名任何其他合规服务。**为了不跟审核员玩猜谜游戏，我直接加上 Apple 登录。**

## 条文规定的五种例外

Apple 列出了五种不需要额外登录方式的情况：

1. **你的 App 只用自己的账号系统**，比如邮箱加密码，或者通过邮件发送验证码。
2. 你的 App 是第三方应用商店，或通过第三方应用商店分发，并使用该商店专属的登录方式。
3. 你的 App 属于教育、企业或商务类，要求使用已有的学校或企业账号。
4. 你的 App 使用由政府或行业支持的电子身份系统。
5. 你的 App 是某个特定第三方服务的客户端：用户登录自己的邮箱或社交网络账号，访问自己的内容。

在看这些例外之前，先问自己一个问题：你的 App 真的需要账号吗？如果不需要，Guideline 5.1.1(v) 要求它在不登录的情况下也能使用，我在 [Guideline 5.1.1 指南](https://devoria.fr/zh-hans/blog/guideline-5-1-1-app-store-rejection-fix)里讲过。

| 你的登录界面      | 适用 4.8 吗？ |
| ----------------- | ------------- |
| 没有账号          | 否            |
| 只有邮箱或验证码  | 否            |
| 只有 Google       | 是            |
| Google 和邮箱     | 是，大概率    |
| Google 和 Apple   | 是，且合规    |
| 已有的学校账号    | 否            |
| Google 仅用于导入 | 否，没有账号  |

## 在 Expo App 里添加“Sign in with Apple”

### 1. 安装模块并声明能力

```bash
npx expo install expo-apple-authentication
```

Expo 文档接着要求在 App 配置里开启这项能力：

```json
{
  "expo": {
    "ios": {
      "usesAppleSignIn": true,
      "infoPlist": { "CFBundleAllowMixedLocalizations": true }
    }
  }
}
```

第二行让按钮按 iPhone 的系统语言显示。用 EAS Build 时，这项能力会在构建时在你的 App ID 上开启。**这是原生设置：它只能随新构建发布，永远不能通过远程更新下发。**

我在复查自己套件的起步代码时发现一个坑：这项能力要求签名，哪怕只是在模拟器上运行。在一台没有“Apple Development”证书的 Mac 上，本地编译会失败，报错“No code signing certificates are available to use”。解决办法：只在认证服务器配置好之后才开启 Apple 登录。

### 2. 显示官方按钮，和 Google 一样醒目

[Apple 的设计规范](https://developer.apple.com/design/human-interface-guidelines/sign-in-with-apple)说得很明确：Apple 按钮不能比其他登录按钮小，也不能需要滚动屏幕才看得到。Expo 的组件绘制的就是官方按钮，标题也是 Apple 允许的。

```tsx
import * as AppleAuthentication from "expo-apple-authentication";
import { useEffect, useState } from "react";

export function BoutonApple({ onPress }: { onPress: () => void }) {
  const [disponible, setDisponible] = useState(false);

  useEffect(() => {
    AppleAuthentication.isAvailableAsync().then(setDisponible);
  }, []);

  // Android 和 Web：没有 Apple 登录，就不显示按钮。
  if (!disponible) return null;

  return (
    <AppleAuthentication.AppleAuthenticationButton
      buttonType={AppleAuthentication.AppleAuthenticationButtonType.CONTINUE}
      buttonStyle={AppleAuthentication.AppleAuthenticationButtonStyle.BLACK}
      cornerRadius={12}
      style={{ width: "100%", height: 50 }}
      onPress={onPress}
    />
  );
}
```

Expo 特别说明，没有宽度和高度时按钮不会显示。颜色和圆角通过 `buttonStyle` 和 `cornerRadius` 设置，而不是通过 style。

### 3. 在 Supabase 中建立会话

```ts
import * as AppleAuthentication from "expo-apple-authentication";
import { supabase } from "./supabase";

export async function connexionApple(): Promise<"ok" | "annule"> {
  try {
    const credential = await AppleAuthentication.signInAsync({
      requestedScopes: [
        AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
        AppleAuthentication.AppleAuthenticationScope.EMAIL,
      ],
    });
    if (!credential.identityToken) throw new Error("缺少 Apple 令牌");
    const { error } = await supabase.auth.signInWithIdToken({
      provider: "apple",
      token: credential.identityToken,
    });
    if (error) throw error;
    // 名字只在第一次授权时返回：马上保存。
    const prenom = credential.fullName?.givenName;
    if (prenom) await supabase.auth.updateUser({ data: { prenom } });
    return "ok";
  } catch (e) {
    if ((e as { code?: string }).code === "ERR_REQUEST_CANCELED")
      return "annule";
    throw e;
  }
}
```

有四个细节很重要，来自 [Supabase 文档](https://supabase.com/docs/guides/auth/social-login/auth-apple)、Expo 文档和 Apple 的设计规范：

- **在 Supabase 里，把你的 Bundle ID 填进** Apple 提供商的 Client IDs。纯原生 App 登录不需要密钥。如果你在 Expo Go 里测试，再加上 `host.exp.Exponent`。
- **名字和邮箱只会返回一次。** 之后的登录 Apple 不再返回：第一次拿到就保存。
- **邮箱可能是中转地址。** Apple 建议之后不要再向用户索要个人邮箱。
- **取消不是错误。** 在 Nolera 上，关闭 Apple 弹出面板不会出现任何红色提示：那是用户主动的操作。

Solys 上的真实经历，2026 年 8 月：App 里有 Apple 和 Google 按钮，但 Supabase 里两个提供商都没开启。代码没问题，修复在服务器端完成，不需要新构建。**Apple 按钮在审核员面前失败，换来的就是 2.1 拒审，而不是 4.8 拒审。**详情见 [Guideline 2.1 指南](https://devoria.fr/zh-hans/blog/app-store-guideline-2-1-rejection-fix)。

### 4. 在真机 iPhone 上测试

Expo 提醒，模拟器只能做有限的测试，而且在 Expo Go 里拿到的标识和正式发布的 App 不一样。在真机 iPhone 上用 [TestFlight](https://devoria.fr/zh-hans/blog/testflight-guide-test-iphone-app) 构建测试登录、退出，再重新登录。

## Apple 登录与账号删除

Guideline 5.1.1(v) 要求在 App 内创建的账号能在 App 内删除。使用 Apple 登录时，[Apple 关于账号删除的页面](https://developer.apple.com/support/offering-account-deletion-in-your-app)多加了一步：用 Sign in with Apple 的 REST API [撤销该用户的令牌](https://developer.apple.com/documentation/signinwithapplerestapi/revoke-tokens)。

撤销需要两样东西：用户的令牌（通过验证授权码获得），以及一个用你的 Sign in with Apple 私钥签名的密钥。**即使原生登录不需要密钥，撤销也需要一个，而且它必须留在你的服务器上。**原因见 [Expo App 中的 API 密钥](https://devoria.fr/zh-hans/blog/expo-api-secret-key-security)。

在 Nolera 上，删除账号时 App 会再次要求 Apple 登录，以拿到一个新的授权码。它把授权码发给一个服务器函数，由函数向 Apple 换取令牌再撤销。如果用户取消，会有清楚的提示，什么都不会删除。流程的其余部分，包括数据、订阅和测试，见 [iOS 账号删除](https://devoria.fr/zh-hans/blog/ios-account-deletion-test-before-app-review)。

## 4.8 拒审后怎么回复 Apple

Apple 的消息给了两条路。要么你加一个同等选项。要么你的 App 已经有了：你在 App Store Connect 里回复，说明是哪一个，以及它为什么满足三个条件。Apple 还建议更新展示登录界面的截图。[回复 App Review](https://developer.apple.com/help/app-store-connect/manage-submissions-to-app-review/reply-to-app-review-messages/) 的流程和其他规则一样。

下面是一个英文模板，按需修改（替换构建号）：

```text
Hello,

Thank you for your review.

Build X adds Sign in with Apple as an equivalent login option.
It appears on the same screen as Google Sign-In, with the same
size, and is visible without scrolling.

How to verify: launch the app, open the sign-in screen and
tap "Continue with Apple".

We also updated the screenshots that show the sign-in screen.

Best regards,
```

## 提交前的 4.8 检查清单

- 你清楚自己的 App 是否需要账号。不需要的话，它可以不登录使用。
- 如果 Google、Facebook 或 X 能创建账号，Apple 登录就在同一个界面上。
- Apple 按钮是官方按钮，和其他按钮一样大，无需滚动就能看到。
- 服务器端已开启 Apple 提供商，并填好了你的 Bundle ID。
- 取消后回到登录界面，没有错误提示。
- 名字和邮箱在第一次登录时就已保存。
- 账号删除时从你的服务器撤销 Apple 令牌。
- 所有内容都在真机 iPhone 上测试过，用的是从没登录过这个 App 的 Apple 账号。
- 你的截图展示的登录界面和提交的构建一致。

## 重新提交前先修好拒审问题

如果你的 App 刚因 4.8 被拒，[Apple Review Kit](https://devoria.fr/zh-hans/kits/app-review) 汇总了我每次提交前检查的内容，还附带两个 skill，能在 Claude Code 里复查你的项目，并在 Apple 拒审时帮你准备回复。想要真人帮你看，[跟我预约一小时](https://devoria.fr/zh-hans/coaching)：我们一起读拒审消息，看看你的登录界面。被拒后的完整处理步骤见 [App 被 Apple 拒绝](https://devoria.fr/zh-hans/expertise/app-rejected-by-apple)页面。

如果你正准备第一次上架，[做一下免费诊断](https://devoria.fr/zh-hans/diagnostic)：它会告诉你先攻克哪一步，并把我的 Apple 防拒审清单发给你。

没人能保证 Apple 一定会通过你的 App。但在正确的位置加上 Apple 登录，至少能把这条拒审原因从清单上划掉。

## 常见问题

### iOS 上必须提供 Apple 登录吗？

不是所有情况都必须。只有当你的 App 提供 Google 或 Facebook 等第三方登录来创建主账号时才需要。从 2024 年 1 月起，可以用其他同等服务代替，但 Apple 只点名 Apple 登录是合规的。

### “Guideline 4.8 - Design - Login Services”是什么意思？

这是 Apple 拒审消息里的标题。意思是你的 App 提供了第三方登录，却没有提供一个同等选项：只收集姓名和邮箱、允许隐藏邮箱、未经同意不用于广告。

### 在 Google 之外提供邮箱注册够不够？

不一定。条文要求的是能让用户保持邮箱私密的服务，而普通注册表单恰恰要填邮箱。Apple 没有就这种情况公开表态，它的拒审消息只点名 Apple 登录。我不会冒这个险。

### Android 上需要提供 Apple 登录吗？

不需要。4.8 是 App Store 的规则，而且 Expo 的模块只在 iOS 上工作。在 Android 上，`isAvailableAsync()` 返回 false：Apple 按钮不会显示，可以只保留 Google。

### 4.8 拒审后需要新构建吗？

大多数情况下需要。Apple 登录需要一项原生能力，在构建时开启。远程更新无法加上它。唯一的例外：你的 App 已经有合规的选项，只需在回复里向 Apple 说明即可。


## 你的项目

[Apple Review Kit](https://devoria.fr/zh-hans/kits/app-review)：我在用的 App Store 审核检查清单、我被 Apple 拒绝后的修改、给审核员的备注，以及两个审查你 App 的 Claude Code skills。29 €。

[iOS Kit](https://devoria.fr/zh-hans/kits/ios)：用 Claude Code 做你的 iPhone App：我自己 App 的起步代码、检查其工作的 skills，以及 Apple Review Kit、App Store Screenshots Kit 和 ASO Kit。129,99 €。
