简体   繁体   English

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

[英]React Admin how to use Basic Authentification ? In my sample, Auth headers are well sent to the entrypoint, but not to all others endpoints

i have an api that runs under /api It requires Basic Http authentification (no needs of JWT thanks to this article https://jolicode.com/blog/why-you-dont-need-jwt ). 我有一个在/ api下运行的api,它需要基本的Http身份验证(由于本文https://jolicode.com/blog/why-you-dont-need-jwt ,因此无需JWT)。 So i configured my authProvider and my fetchHydra to build the Header. 所以我配置了我的authProvider和fetchHydra来构建Header。

This header is well sent to those 3 main endpoints: 此标头很好地发送到了这3个主要端点:

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

But then, it try to call all resources endpoint without using Basic Http so they all response with HTTP 401. 但是,然后,它尝试不使用Basic Http来调用所有资源终结点,因此它们都使用HTTP 401进行响应。

Here is my code: 这是我的代码:

// 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();
    }
}

My application is using PHP Symfony Api-Platform (2.4.5) and Api-Platform Admin (0.6.3 which embed the react admin ^2.7.0) I pushed the repo on github: https://github.com/Rebolon/LibraryManagementSystem 我的应用程序使用PHP Symfony Api-Platform(2.4.5)和Api-Platform Admin(0.6.3嵌入了react admin ^ 2.7.0),我在github上推送了仓库: https : //github.com/Rebolon/图书馆管理系统

Ok, so the problem is not related of my code. 好的,所以问题与我的代码无关。 Oh yeah, it's not my fault. 哦,是的,这不是我的错。 In fact it's related to version 0.6.3 of package @api-platform/admin which breaks the authentication system. 实际上,它与软件包@ api-platform / admin的0.6.3版本有关,该版本破坏了身份验证系统。 The solution is to rollback to version 0.6.2 of the package. 解决方案是回滚到该软件包的0.6.2版本。

Thanks to this thread: https://github.com/api-platform/admin/issues/185 感谢这个线程: https : //github.com/api-platform/admin/issues/185

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM