如何在 hasura react admin 中动态更新数据提供者标头?

Posted

技术标签:

【中文标题】如何在 hasura react admin 中动态更新数据提供者标头?【英文标题】:How to update data provider headers dynamically in hasura react admin? 【发布时间】:2019-12-18 15:15:33 【问题描述】:

我正在尝试使用 react-admin 和 hasura 数据提供程序进行需要身份验证的应用程序,我需要在登录成功后更改标题。现在,只有在我重新加载页面时才会更新标题,否则会引发此错误:

"path":"$","error":"Malformed Authorization header","code":"invalid-headers"

这是我当前的 app.js 代码:

import React,  useEffect  from 'react';

import  Admin, Resource,   from 'react-admin';
import Dashboard from './Dashboard';
import hasuraDataProvider from 'ra-data-hasura';
import authProvider from './authProvider';
import Cookies from "react-cookie";
import  AssociadoList, AssociadoShow  from "./Associado";
import portugueseMessages from 'ra-language-portuguese';
import LoginPage from "./Login";
import "./App.scss";
const ucookies = new Cookies();

const messages = 
  'pt': portugueseMessages,
;
const i18nProvider = locale => messages[locale];
const dataProvider = () => 
  const dataProvider = hasuraDataProvider(process.env.REACT_APP_HASURA_URL,  "content-type": "application/json", "Authorization": "Bearer " +  ucookies.get("authToken"));
  return dataProvider;

function App() 
  return (
    <Admin
      dataProvider=dataProvider()
      authProvider=authProvider
      dashboard=Dashboard
      loginPage=LoginPage
      locale="pt" i18nProvider=i18nProvider
    >
      <Resource name="adear.associado" list=AssociadoList options= label: 'Associado'  show=AssociadoShow />
    </Admin>
  );


export default App;

这是authprovider的代码:

import  AUTH_LOGIN, AUTH_LOGOUT, AUTH_ERROR, AUTH_CHECK  from 'react-admin';
import graphql from './graphqlClient';
import Cookies from 'universal-cookie';
import  GraphQLClient  from 'graphql-request';
const cookies = new Cookies();

const LOGIN = `
    mutation($username:String!, $password:String!)
        login(username: $username, password: $password)
            token
        
    
`;
const ME = `
    query 
        me 
            username
        
    
`;

export default (type, params) => 

    if (type === AUTH_LOGIN) 
        const  username, password  = params;
        return graphql.request(LOGIN,  username, password ).then(data => 
            const token = data.login.token;

            cookies.set("authToken", token,  path: "/", sameSite: "strict" );
            localStorage.setItem("loggedIn", true);
            //localStorage.setItem("reloaded", false);

        );
    
    if (type === AUTH_LOGOUT) 
        cookies.set("authToken", "",  path: "/", sameSite: "strict" );
        localStorage.setItem("loggedIn", false);
        localStorage.removeItem("reloaded");
        return Promise.resolve();
    
    if (type === AUTH_ERROR) 
        const graphqlauth = new GraphQLClient(process.env.REACT_APP_HASURA_ENDPOINT, 
            headers: 
                authorization: 'Bearer ' + cookies.get('authToken'),
            ,
        )
        return graphqlauth.request(ME).then(data =>  return (data.me.username) ? Promise.resolve() : Promise.reject(); ).catch(e => 
            cookies.set("authToken", "",  path: "/", sameSite: "strict" );
            localStorage.setItem("loggedIn", false);

        );

    
    if (type === AUTH_CHECK)  
        const graphqlauth = new GraphQLClient(process.env.REACT_APP_HASURA_ENDPOINT, 
            headers: 
                authorization: 'Bearer ' + cookies.get('authToken'),
            ,
        )
        return graphqlauth.request(ME).then(data =>  return (data.me.username) ? Promise.resolve() : Promise.reject(); );
        //return cookies.get('authToken') &&  cookies.get('authToken') !== "" ? Promise.resolve() : Promise.reject();
    
    return Promise.resolve();
;

当我重新加载页面时,错误不会发生。我尝试使用状态,但似乎无法更改标题。

【问题讨论】:

【参考方案1】:

ra-data-hasura 数据提供程序的较新版本 (0.0.7) 添加了对 httpClient 传递动态标头的支持。

它使用 react-admin 的 fetchUtils.fetchJson() 作为 HTTP 客户端。因此,要将自定义标头添加到您的请求中,您只需将 fetchUtils.fetchJson() 调用包装在您自己的函数中:

const httpClient = (url, options = ) => 
  if (!options.headers) 
      options.headers = new Headers( Accept: 'application/json' );
  
  // add your own headers here
  options.headers.set('Authorization', 'Bearer xxxxx');
  return fetchUtils.fetchJson(url, options);
;
const dataProvider = hasuraDataProvider('http://localhost:8080', httpClient);

【讨论】:

以上是关于如何在 hasura react admin 中动态更新数据提供者标头?的主要内容,如果未能解决你的问题,请参考以下文章

Hasura 上的客户端数据备份

为啥我使用 graphql > hasura > postgres 保存日期时出错

如何在Hasura上创建cron作业?

Hasura:如何过滤数组内部

如何在 React Typescript 应用程序中导入 react-admin?

如何在 react-admin 中禁用乐观 UI 更新?