ra-data-json-server 与 ra-auth-cognito 结合

问题描述 投票:0回答:1

在开始之前,我对 React 很陌生,但对 AWS 却不太熟悉,这导致我选择了一个超出我能力范围的项目。

我正在构建一个非常简单的 CRUD 网站,其中包含帖子列表和发布这些帖子的用户列表。我开始在这里学习本教程 https://marmelab.com/react-admin/Tutorial.html 最后我开始将其扩展到 AWS 部署中。

表面上是一个带有 React 站点的 S3 存储桶,以及用于提供所有数据接口的 API,所有这些都位于 Cloudfront 发行版后面。

我不希望每个人和他的狗都有访问权限,所以我想在我的服务前面实现一个 Cognito 身份验证提供程序,如下所示:

我的问题是,本教程引导我使用

ra-data-json-server
模块设置 dataProvider。
ra-auth-cognito
模块提供了我登录所需的内容并正常工作,有效的 Cognito 用户可以登录仪表板,但他们无法通过 API 调用访问任何数据。

我的 App.tsx 文件包含

...
import { CognitoAuthProvider, Login } from 'ra-auth-cognito';
import { CognitoUserPool } from 'amazon-cognito-identity-js';

const userPool = new CognitoUserPool({
  UserPoolId: "us-east-1_MyPoOlId",
  ClientId: "MyClIeNtId",
});

const authProvider = CognitoAuthProvider(userPool);

export const App = () => (
  <Admin authProvider={authProvider} dataProvider={dataProvider} dashboard={Dashboard} loginPage={Login} >
    <Resource name="posts" list.......

我的 dataProvider.ts 看起来像

import jsonServerProvider from "ra-data-json-server";

// I know i need a httpClient function here (I think)

export const dataProvider = (() => {
    return jsonServerProvider("https://my-url/api/");
})();

我一直在阅读文档https://marmelab.com/react-admin/Authentication.html,据我了解,我可以将 httpClient 作为第二个参数传递给 jsonServerProvider,提供的代码块会导致错误“dataProvider 抛出了一个错误。它应该返回一个被拒绝的 Promise”

我也尝试遵循这篇文章的建议将ra-cognito合并到react-admin中并解决ra-data-json-server承诺问题虽然这个用户使用的是Amplify,但我没有使用,但是它对我不起作用

问题是,我现在可以保护管理面板,但是在启用身份验证的情况下调用后端 API 的任何操作都不会发送身份验证,该 API 需要一个不记名令牌,该令牌会在我点击它时正确回复预期的数据通过具有有效不记名令牌的邮递员。

如何将调用链接到 API,以便将登录的令牌传递到 ra-data-json-server 发出的 api 调用

reactjs aws-api-gateway amazon-cognito react-admin
1个回答
1
投票

感谢您首先提供详细的问题:)

我相信你缺少两件事来让它发挥作用。

1.获取当前登录用户的token

ra-auth-cognito
几乎是在内部完成的,但不幸的是它没有记录如何获取当前登录用户的 JWT 令牌。这是获取它的一种方法(灵感来自
authProvider.ts
):

        const getJwtToken = async () => {
            return new Promise((resolve, reject) => {
                const user = userPool.getCurrentUser();

                if (!user) {
                    return reject();
                }

                user.getSession((err, session: CognitoUserSession) => {
                    if (err) {
                        return reject(err);
                    }
                    if (!session.isValid()) {
                        return reject();
                    }
                    const token = session.getIdToken().getJwtToken();
                    return resolve(token);
                });
            });
        }

2.使用token查询API

我相信使用自定义

httpClient
确实是最好的方法。你几乎已经成功了:).

这是改编自

ra-data-json-server
文档的示例

import { fetchUtils, Admin, Resource } from 'react-admin';
import jsonServerProvider from 'ra-data-json-server';

const getJwtToken = async () => { /* ... */ };
const httpClient = async (url: string, options: any = {}) => {
    options.user = {
        authenticated: true,
        token: await getJwtToken(),
    };
    return fetchUtils.fetchJson(url, options);
};
const dataProvider = jsonServerProvider('https://jsonplaceholder.typicode.com', httpClient);

render(
    <Admin dataProvider={dataProvider} title="Example Admin">
       ...
    </Admin>,
    document.getElementById('root')
);

这应该足以将承载令牌包含到每个 API 调用中。

希望这有帮助! :)

© www.soinside.com 2019 - 2024. All rights reserved.