首页
/ AWS Amplify JS 中 Sign in With Apple 账号删除的完整解决方案

AWS Amplify JS 中 Sign in With Apple 账号删除的完整解决方案

2025-05-24 05:42:03作者:晏闻田Solitary

背景介绍

在使用 AWS Amplify JS 开发 React Native 应用时,许多开发者会选择集成苹果的 Sign in With Apple (SIWA) 作为第三方登录方式。然而,当用户通过 Amplify 的 deleteUser 方法删除账号后,再次尝试使用 SIWA 登录时往往会遇到各种问题。这是因为 deleteUser 仅删除了 Cognito 用户池中的用户记录,而没有清理苹果端的关联账号。

问题本质

SIWA 的工作机制会在苹果服务器上创建一个中继邮箱账号,这个账号与你的应用绑定。当调用 deleteUser 时,虽然 Cognito 用户被删除,但苹果服务器上的这个关联关系依然存在。这会导致以下问题:

  1. 再次登录时苹果会认为用户已经存在,提供不同的登录界面
  2. 可能不会返回完整的用户属性(如姓名等)
  3. 在某些配置下会导致登录失败

技术解决方案

要彻底解决这个问题,我们需要在删除用户的同时,也通知苹果服务器撤销相关令牌和中继账号。以下是完整的实现方案:

1. 配置用户属性映射

首先,我们需要在 Amplify 的 auth 配置中将苹果颁发的 refresh_token 映射到一个自定义用户属性:

export const auth = defineAuth({
  loginWith: {
    externalProviders: {
      signInWithApple: {
        // 其他SIWA配置...
        attributeMapping: {
          custom: {
            "custom:apple_refresh_token": "refresh_token",
          },
        },
      }
    }
  },
  userAttributes: {
    "custom:apple_refresh_token": {
      mutable: true,
      dataType: "String",
    },
  }
});

2. 生成客户端密钥

要调用苹果的令牌撤销API,我们需要使用开发者的认证密钥生成一个客户端密钥:

import jwt from "jsonwebtoken";

function generateClientSecretJWT() {
  const authKey = `-----BEGIN PRIVATE KEY-----
  YOUR_AUTH_KEY_HERE
  -----END PRIVATE KEY-----`;
  
  return jwt.sign(
    {
      iss: "YOUR_TEAM_ID",
      iat: Math.floor(Date.now() / 1000),
      exp: Math.floor(Date.now() / 1000) + 8640 * 180,
      aud: "https://appleid.apple.com",
      sub: "YOUR_CLIENT_ID",
    },
    authKey,
    {
      algorithm: "ES256",
      header: {
        alg: "ES256",
        kid: "YOUR_KEY_ID",
      },
    }
  );
}

3. 实现令牌撤销

最后,在删除用户前调用苹果的撤销API:

async function revokeAppleToken() {
 const userAttributes = await fetchUserAttributes();
 const appleRefreshToken = userAttributes['custom:apple_refresh_token'];
   
 const response = await fetch('https://appleid.apple.com/auth/revoke', {
   method: 'POST',
   headers: { 'content-type': 'application/x-www-form-urlencoded' },
   body: new URLSearchParams({
     'client_id': 'YOUR_CLIENT_ID',
     'client_secret': generateClientSecretJWT(),
     'token': appleRefreshToken,
     'token_type_hint': 'refresh_token'
   })
 });
 
 if(response.ok) {
   await deleteUser(); // 现在可以安全删除用户
 }
}

最佳实践建议

  1. 属性配置:将用户属性(如姓名等)设置为非必填,因为SIWA在后续登录时可能不会提供这些信息

  2. 错误处理:实现完善的错误处理,考虑到网络请求可能失败的情况

  3. 用户体验:在UI上明确告知用户账号删除的完整流程

  4. 测试验证:在开发阶段充分测试各种边界情况

总结

通过上述方案,开发者可以完整实现SIWA账号的删除流程,解决用户重复注册和属性缺失的问题。这种端到端的账号管理方案能显著提升用户体验,是集成第三方登录时需要考虑的重要环节。

对于使用其他社交登录(如Google、Facebook)的开发者,也可以参考类似的思路,在删除用户时同步清理第三方平台的关联信息。

登录后查看全文
热门项目推荐
相关项目推荐