You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Amplify/Cognito中配合Auth.federatedSignIn()使用@auth owner指令

问题解答

问题根源

你当前遇到的@auth(rules: [{ allow: owner }])不生效的核心原因是:你调用的Auth.federatedSignIn()(传入身份提供商名称、令牌、用户信息的重载方法)走的是**Cognito身份池(联邦身份)**的认证流程,只会颁发IAM访问凭证,不会在Cognito用户池中生成对应用户条目。而@auth(rules: [{ allow: owner }])默认依赖Cognito用户池颁发的ID令牌中的sub/cognito:username声明,因此无法正常识别用户身份做权限隔离。

可行解决方案

你不需要使用托管UI跳转,只要调整认证流程,将Facebook原生登录获取的令牌,兑换为Cognito用户池的JWT令牌即可,具体步骤如下:

  • 第一步:在AWS Cognito用户池控制台中,将Facebook配置为第三方身份提供商(IdP),填入你的Facebook应用ID、密钥,配置属性映射(比如将Facebook返回的id映射为用户池的username,email映射为用户池的email)。
  • 第二步:保留你当前用capacitor-facebook-login获取Facebook访问令牌的逻辑,替换后续的认证逻辑:不再调用原有的身份池版Auth.federatedSignIn(),而是用Facebook令牌兑换Cognito用户池的JWT令牌,再手动注入Amplify Auth会话。

参考代码如下:

import { Auth } from 'aws-amplify';
import { CognitoIdentityProviderClient, InitiateAuthCommand } from "@aws-sdk/client-cognito-identity-provider";

// 初始化Cognito Identity Provider客户端,替换为你自己的用户池配置
const cognitoClient = new CognitoIdentityProviderClient({
  region: "你的Cognito用户池所在区域",
});

const FBLogIn = async () => {
  const result = await FacebookLogin.login({ permissions: FACEBOOK_PERMISSIONS });
  const { email } = await FacebookLogin.getProfile({ fields: ['email'] });
  const fbAccessToken = result.accessToken.token;
  const fbUserId = result.accessToken.userId;

  try {
    // 调用Cognito用户池接口,用Facebook令牌兑换用户池JWT
    const authResponse = await cognitoClient.send(new InitiateAuthCommand({
      AuthFlow: "CUSTOM_AUTH",
      ClientId: "你的Cognito用户池App客户端ID",
      AuthParameters: {
        USERNAME: fbUserId,
        PASSWORD: fbAccessToken,
      }
    }));

    const { IdToken, AccessToken, RefreshToken } = authResponse.AuthenticationResult;
    // 手动设置Amplify登录会话
    const userSession = {
      getIdToken: () => ({ getJwtToken: () => IdToken }),
      getAccessToken: () => ({ getJwtToken: () => AccessToken }),
      getRefreshToken: () => ({ getToken: () => RefreshToken }),
      isValid: () => true
    };
    await Auth.setSignInUserSession(userSession);

    // 此时Cognito已自动在用户池中创建对应用户,后续GraphQL请求的@auth(allow: owner)规则会正常生效
  } catch (error) {
    console.log(error)
  }
}

你需要额外在Cognito用户池配置自定义认证Lambda触发器,用来验证Facebook令牌的有效性:触发器接收Facebook用户ID和令牌,调用Facebook令牌验证接口确认有效性后返回认证成功即可。

如果不想编写Lambda,也可以在配置完Cognito用户池的Facebook IdP后,直接通过Cognito OAuth2 token端点的token-exchange授权类型直接兑换用户池JWT,不需要额外开发触发器。

配置完成后,你可以直接在GraphQL Schema中使用@auth(rules: [{ allow: owner }])规则,Cognito会自动识别当前登录用户的sub作为所有者标识,实现用户仅能查看自有数据的权限隔离。


内容的提问来源于stack exchange,提问作者webdog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 01:24:02