javascript - React Admin 如何使用基本身份验证?在我的示例中,Auth header 很好地发送到入口点,但未发送到所有其他端点

标签 javascript reactjs react-admin api-platform.com

我有一个在/api 下运行的 api 它需要基本的 Http 身份验证(由于本文 https://jolicode.com/blog/why-you-dont-need-jwt ,不需要 JWT )。 所以我配置了 authProvider 和 fetchHydra 来构建 header 。

这个 header 很好地发送到了这 3 个主要端点:

  • /api
  • /api/docs.jsonld
  • /入口点

但是,它尝试在不使用 Basic Http 的情况下调用所有资源端点,因此它们都以 HTTP 401 响应。

这是我的代码:

// admin.js (app main resource)

import React from 'react';
import parseHydraDocumentation from '@api-platform/api-doc-parser/lib/hydra/parseHydraDocumentation';
import { HydraAdmin, hydraClient, fetchHydra as baseFetchHydra } from '@api-platform/admin';
import ReactDOM from 'react-dom';
import authProvider from './src/authProvider';
import { Route, Redirect } from 'react-router-dom';

const entrypoint = document.getElementById('api-entrypoint').innerText;
// Fetch api route with Http Basic auth instead of JWT Bearer system
const fetchHeaders = {"Authorization": `Basic ${btoa(`${localStorage.getItem('username')}:${localStorage.getItem('token')}`)}`};
// original system with JWT
// const fetchHeaders = {'Authorization': `Bearer ${localStorage.getItem('token')}`};
const fetchHydra = (url, options = {}) => baseFetchHydra(url, {
    ...options,
    headers: new Headers(fetchHeaders),
});
const dataProvider = api => {
    return hydraClient(api, fetchHydra);
}
const apiDocumentationParser = entrypoint =>
    parseHydraDocumentation(entrypoint, {
        headers: new Headers(fetchHeaders),
    }).then(
        ({ api }) => ({ api }),
        result => {
            const { api, status } = result;

            if (status === 401) {
                return Promise.resolve({
                    api,
                    status,
                    customRoutes: [
                        <Route path="/" render={() => <Redirect to="/login" />} />,
                    ],
                });
            }

            return Promise.reject(result);
        }
    );

ReactDOM.render(
    <HydraAdmin
        apiDocumentationParser={apiDocumentationParser}
        authProvider={authProvider}
        entrypoint={entrypoint}
        dataProvider={dataProvider}
    />, document.getElementById('api-platform-admin'));

// admin/src/authProvider.js

import { AUTH_LOGIN, AUTH_LOGOUT, AUTH_ERROR, AUTH_CHECK } from 'react-admin';

// Change this to be your own authentication token URI.
const authenticationTokenUri = `${document.getElementById('api-entrypoint').innerText}/login`;

export default (type, params) => {
    switch (type) {
        case AUTH_LOGIN:
            const { username, password } = params;
            const request = new Request(authenticationTokenUri, {
                method: 'POST',
                body: JSON.stringify({ username: username, password }),
                headers: new Headers({ 'Content-Type': 'application/json' }),
            });

            return fetch(request)
                .then(response => {
                    if (response.status < 200 || response.status >= 300) throw new Error(response.statusText);

                    return response.json();
                })
                .then(({ token }) => {
                    localStorage.setItem('username', username);
                    localStorage.setItem('token', token); // The token is stored in the browser's local storage
                    window.location.replace('/');
                });

        case AUTH_LOGOUT:
            localStorage.removeItem('username');
            localStorage.removeItem('token');
            break;

        case AUTH_ERROR:
            if (401 === params.status || 403 === params.status) {
                localStorage.removeItem('username');
                localStorage.removeItem('token');

                return Promise.reject();
            }
            break;

        case AUTH_CHECK:
            return localStorage.getItem('token') ? Promise.resolve() : Promise.reject();

        default:
            return Promise.resolve();
    }
}

我的应用程序正在使用 PHP Symfony Api-Platform (2.4.5) 和 Api-Platform Admin(0.6.3,其中嵌入了 React admin ^2.7.0) 我在github上推送了repo:https://github.com/Rebolon/LibraryManagementSystem

最佳答案

好的,所以问题与我的代码无关。哦,是的,这不是我的错。 事实上,它与 @api-platform/admin 包的 0.6.3 版本有关,该版本破坏了身份验证系统。 解决方案是回滚到软件包的0.6.2版本。

感谢此线程:https://github.com/api-platform/admin/issues/185

关于javascript - React Admin 如何使用基本身份验证?在我的示例中,Auth header 很好地发送到入口点,但未发送到所有其他端点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57184540/

相关文章:

php - js 相当于 php 的 foreach($arr as $k=>$v)

javascript - 编写 Javascript 队列

javascript - 在单个 Canvas 中的元素数组中添加 Click 事件

javascript - 为什么在一种情况下我在 ExpressJS 中遇到 cors 错误,而在另一种情况下却没有?

reactjs - react-admin 登录页面中的背景图片

javascript - i18nProvider 为默认语言环境的消息返回了一个 Promise。 react 管理员

javascript - d3.json() 和 JSON.parse() 产生相同的结果吗?

javascript - 单击“关闭”时无法删除列表项?

reactjs - 嵌套菜单(子菜单)

javascript - React.js - 使用 Enzyme 模拟点击