Appsync Resolver 声明中没有电子邮件

dev*_*bar 6 amazon-cognito aws-appsync aws-amplify

我创建了一个使用电子邮件地址 ($context.identity.claims.email) 的解析程序。我在 AWS 控制台“查询”部分测试了我的查询,一切正常,因为 $context.identity.claims 看起来符合预期;

{
    sub: 'xxx-xxx-xxx-xxx-xxx',
    aud: 'xxxxxxxxx',
    email_verified: true,
    sub: 'xxx-xxx-xxx-xxx-xxx',
    token_use: 'id',
    auth_time: 1563643503,
    iss: 'https://cognito-idp.ap-southeast-1.amazonaws.com/ap-southeast-1_xxxxx',
    'cognito:username': 'xxxx',
    exp: 1563647103,
    iat: 1563643503,
    email: 'xxx@xxx.xxx'
}
Run Code Online (Sandbox Code Playgroud)

一切看起来都不错,所以让我们在我的 React 应用程序中使用它,该应用程序使用 AWS Amplify 代码进行身份验证。它现在不起作用,那是因为索赔部分没有“电子邮件”!看起来像这样;

{
    sub: 'xxx-xxx-xxx-xxx-xxx',
    event_id: 'xxx-xxx-xxx-xxx-xxx',
    token_use: 'access',
    scope: 'aws.cognito.signin.user.admin',
    auth_time: 1563643209,
    iss: 'https://cognito-idp.ap-southeast-1.amazonaws.com/ap-southeast-1_xxxx',
    exp: 1563646809,
    iat: 1563643209,
    jti: 'xxx-xxx-xxx-xxx-xxx',
    client_id: 'xxxx',
    username: 'xxxx'
}
Run Code Online (Sandbox Code Playgroud)

谁能帮我解释为什么电子邮件显示在 AWS 控制台查询中,但当我从自己的客户端调用它时却没有显示?

ggr*_*fin 8

可以通过传入函数将 Amplify 配置为包含每个 graphql 请求的当前 ID 令牌。两个配置选项如下所示:

import { Auth } from 'aws-amplify';

const getIdToken = async () => ({
  Authorization: (await Auth.currentSession()).getIdToken().getJwtToken()
});

const aws_exports = {
  aws_appsync_graphqlEndpoint: 'https://****.appsync-api.us-east-2.amazonaws.com/graphql',
  aws_appsync_region: 'us-east-2',
  aws_appsync_authenticationType: 'AMAZON_COGNITO_USER_POOLS',

  // OPTION 1
  graphql_headers: getIdToken,

  // OPTION 2
  // API: {
  //   graphql_headers: getIdToken
  // },

  Auth: {
    identityPoolId: 'us-east-2:********-****-****-****-************',
    region: 'us-east-2',
    userPoolId: 'us-east-2_*********',
    userPoolWebClientId: '*************************',
    type: 'AMAZON_COGNITO_USER_POOLS'
  }
};

export default aws_exports;
Run Code Online (Sandbox Code Playgroud)
Amplify.configure(awsconfig);
Run Code Online (Sandbox Code Playgroud)

请注意解析器在访问令牌和 ID 令牌之间可用的不同声明。

client_id访问令牌将提供、jti、 和 等声明scope,而 ID 令牌声明提供email、phone_number等,以及其他声明,如aud、cognito:roles和cognito:username。

访问令牌

{
  "claims": {
    "auth_time": 1581438574,
    "client_id": "*************************",
    "cognito:groups": [
      "Admin"
    ],
    "event_id": "ec70594c-b02b-4015-ad0b-3c207a18a362",
    "exp": 1581442175,
    "iat": 1581438575,
    "iss": "https://cognito-idp.us-east-2.amazonaws.com/us-east-2_*********",
    "jti": "351d2d5f-13c3-4de8-ba7c-b3c5a9e46ca6",
    "scope": "aws.cognito.signin.user.admin",
    "sub": "********-****-****-****-************",
    "token_use": "access",
    "username": "********-****-****-****-************"
  },
  ...
}
Run Code Online (Sandbox Code Playgroud)

身份令牌

{
  "claims": {
    "address": {
      "formatted": "1984 Newspeak Dr"
    },
    "aud": "....",
    "auth_time": 1581438671,
    "birthdate": "1984-04-04",
    "cognito:groups": [
      "Admin"
    ],
    "cognito:roles": [
      "arn:aws:iam::012345678901:role/us-east-2-ConsumerRole"
    ],
    "cognito:username": "********-****-****-****-************",
    "email": "winston.smith@oceania.gov",
    "email_verified": true,
    "event_id": "e3087488-bfc8-4d08-a44c-089c4ae7d8ec",
    "exp": 1581442271,
    "gender": "Male",
    "iat": 1581438672,
    "iss": "https://cognito-idp.us-east-2.amazonaws.com/us-east-2_*********",
    "name": "WINSTON SMITH",
    "phone_number": "+15551111984",
    "phone_number_verified": false,
    "sub": "********-****-****-****-************",
    "token_use": "id"
  },
  ...
}
Run Code Online (Sandbox Code Playgroud)

测试用amplify-js@2.2.4

来源: https: //github.com/aws-amplify/amplify-js/blob/aws-amplify%402.2.4/packages/api/src/API.ts#L86-L107


dev*_*bar 0

好的,所以我认为它们位于“token_use”元素中。我原来的代码使用了这个函数;

import {API, graphqlOperation} from 'aws-amplify';
import * as queries from '../../graphql/queries';

async function makeCall() {
    let resp = await API.graphql(graphqlOperation(queries.getMeta));
    return resp.data.getMeta;
}
Run Code Online (Sandbox Code Playgroud)

该代码产生了上面观察到的结果。如果我使用以下(非常脏但有效)代码,我会得到上述预期结果;

import {Auth, API, graphqlOperation} from 'aws-amplify';
import axios from 'axios';
import * as queries from '../../graphql/queries';

async function makeCall() {
    const curSesh = await Auth.currentSession();
    const token = curSesh.idToken.jwtToken;
    const resp = await axios({
        method: 'post',
        url: API._options.aws_appsync_graphqlEndpoint,
        data: graphqlOperation(queries.getMeta),
        headers: {
            authorization: token
        }
    });
    return resp.data.data.getMeta;
}

Run Code Online (Sandbox Code Playgroud)

我不会将其标记为已解决,因为我确信有一种更简洁的方法可以使其正常工作。如果有人能阐明它,我很乐意学习。