gpt4 book ai didi

javascript - 如何将 AMAZON_COGNITO_USER_POOLS 与 apollo-client 一起使用

转载 作者:行者123 更新时间:2023-12-04 13:12:13 26 4
gpt4 key购买 nike

我正在尝试用较新的 @aws-amplify 包填充我的 jwtToken,事实证明这有点困难。

尝试运行查询时,我会收到以下错误:Uncaught (in promise) No current user

我可以从源代码中看到,如果我将身份验证类型设置为 AMAZON_COGNITO_USER_POOLS,那么我必须使用 jwt token

        case AUTH_TYPE.AMAZON_COGNITO_USER_POOLS:
case AUTH_TYPE.OPENID_CONNECT:
const { jwtToken = '' } = auth;
promise = headerBasedAuth({ header: 'Authorization', value: jwtToken }, operation, forward);

所以这导致我尝试生成我的 JWT token ,而这正是我的知识让我失望的地方。我知道 jwtToken: async () => (await Auth.currentSession()).getIdToken().getJwtToken(), 返回上面代码中所要求的 promise ...所以我不明白为什么会失败?

_app.js (next.js)

import Amplify from '@aws-amplify/core'
import { Auth } from '@aws-amplify/auth'
import { ApolloProvider } from '@apollo/react-hooks'
import { ApolloLink } from 'apollo-link'
import { createAuthLink } from 'aws-appsync-auth-link'
import { InMemoryCache, ApolloClient } from '@apollo/client'
import { createHttpLink } from 'apollo-link-http'

import awsExports from '../aws-exports'

Amplify.configure(awsExports)
Auth.configure(awsExports)

const url = awsExports.aws_appsync_graphqlEndpoint
const region = awsExports.aws_appsync_region

const auth = {
type: awsExports.aws_appsync_authenticationType,
jwtToken: async () => (await Auth.currentSession()).getIdToken().getJwtToken(),
}
const link = ApolloLink.from([createAuthLink({ url, region, auth }), createHttpLink({ uri: url })])
const client = new ApolloClient({
link,
cache: new InMemoryCache(),
})

const MyApp = function ({ Component, pageProps, router }) {
return (
.....
<ApolloProvider client={client}>
.....
)
}

export default MyApp

最佳答案

jwtToken: async () => (await Auth.currentSession()).getIdToken().getJwtToken()

这是一个部分正确的实现,当用户已经登录时可以正常工作。

Auth.currentSession() 在用户未登录时失败并显示 Uncaught (in promise) No current user

以下将显示操作中的错误

 Amplify.configure(awsExports);

Auth.signOut()
.then(_ => auth.jwtToken())
.then(console.log)
.catch(console.error);

以下是您将获得 token 的示例(替换代码中的用户名和密码)

Amplify.configure(awsExports);

Auth.signIn(<username>, <password>)
.then(_ => auth.jwtToken())
.then(console.log)
.catch(console.error);

此问题的解决方案是确保您在用户登录时请求 token 或确保妥善处理错误。

更新:

如果有任何公共(public)查询,我会说除了 AppSync GraphQL 端点的 Cognito 身份验证之外,还添加基于 api key 的身份验证(AppSync 设置中的其他授权提供程序)。在下面的示例中,idpublicProperty 可以通过 somePublicQuery 使用配置的 API key 访问

type Query {
somePublicQuery:[SomeModel!]!
@aws_api_key
}

type SomeModel {
id: ID! @aws_api_key
privateProperty: String!
publicProperty: String! @aws_api_key
}

如果我引用问题中指出的示例,那么这就是客户端会发生的变化。

headerBasedAuth 可以采用一组 header ,一个用于 api key ,一个用于 Cognito token 。

const headerBasedAuth = async ( authHeaders: Array<Headers> = [], operation, forward) => {
const origContext = operation.getContext();
let headers = {
...origContext.headers,
[USER_AGENT_HEADER]: USER_AGENT,
};

for ( let authHeader of authHeaders) { // Handle the array of auth headers
let { header, value } = authHeader;
if (header && value) {
const headerValue = typeof value === 'function' ? await value.call(undefined) : await value;

headers = {
...{ [header]: headerValue },
...headers
};
}
}

operation.setContext({
...origContext,
headers,
});

return forward(operation);

};

authLink 函数中,您将拥有类似这样的东西,而不是 switch 语句

const { apiKey = '', jwtToken = '' } = auth;
promise = headerBasedAuth([{ header: 'X-Api-Key', value: apiKey }, { header: 'Authorization', value: jwtToken }], operation, forward);

最后 auth 对象看起来像这样

const auth = {
apiKey: awsExports.aws_appsync_apiKey, //Add apiKey to your aws-exports
jwtToken: async () => {
try {
return (await Auth.currentSession()).getIdToken().getJwtToken()
} catch (e) {
console.error(e);
return ""; // In case you don't get the token, hopefully that is a public api and that should work with the API Key alone.
}
}
}

关于javascript - 如何将 AMAZON_COGNITO_USER_POOLS 与 apollo-client 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64055449/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com