如何在react-admin/api-platform/admin中调用自定义端点无需手动加Bearer头?
问题描述
我在项目中采用api-platform/admin(即react-admin)实现了自定义数据展示、JWT认证及登录页等功能,前端加载资源一切正常。我已定义了如下httpClient和apiDocumentationParser,默认数据提供者发起的所有API请求都会自动携带Bearer头:
const getHeaders = (): HeadersInit => { const userToken = token(); return { Authorization: `Bearer ${userToken}`, }; }; const httpClient = (url: URL, options: any = {}) => { return baseFetchHydra(url, { headers: getHeaders, }); }; const apiDocumentationParser = async (entrypointUrl: string) => { //.... }
但我在后端(sf6 + api-platform)新增了一个自定义端点,希望在前端的按钮组件点击时调用该端点。目前我通过fetch手动添加Bearer头可正常发起请求,代码如下:
const doSomething = async (id: string) => { const auth = localStorage.getItem("auth"); const token = JSON.parse(auth ?? "").token; const request = new Request( process.env.REACT_APP_API_URL + "/this_custom_endpoint/{id}".replace("{id}", id), { method: "GET", headers: new Headers({ "Content-Type": "application/json", Authorization: `Bearer ${token}`, }), } ); return fetch(request).then(...).then(...).catch(...); } const DoSomethingButton = () => { const record = useRecordContext(); return ( <Button label="Do something" onClick={() => { const id = record.originId; doSomething(id); }} /> ); };
按钮可正常显示并触发请求,但我希望借助react-admin的方案实现该请求,无需手动添加Bearer头,请问是否可行?
解决方案
完全可行,你可以通过两种方式复用react-admin已配置的认证逻辑,自动携带Bearer头:
方式一:直接复用已定义的httpClient
修改你的doSomething函数,直接调用项目中已配置好的httpClient,它会自动注入Authorization头:
const doSomething = async (id: string) => { const url = new URL(`${process.env.REACT_APP_API_URL}/this_custom_endpoint/${id}`); return httpClient(url, { method: "GET", headers: { "Content-Type": "application/json", }, }) .then(...).then(...).catch(...); };
方式二:使用useHttpClient钩子(推荐)
如果组件处于react-admin上下文环境中,用useHttpClient钩子获取全局http客户端,更贴合react-admin生态,后续配置变更也能自动同步:
import { useHttpClient } from 'react-admin'; const DoSomethingButton = () => { const record = useRecordContext(); const httpClient = useHttpClient(); const doSomething = async (id: string) => { const url = new URL(`${process.env.REACT_APP_API_URL}/this_custom_endpoint/${id}`); return httpClient(url, { method: "GET", headers: { "Content-Type": "application/json", }, }) .then(...).then(...).catch(...); }; return ( <Button label="Do something" onClick={() => { const id = record.originId; doSomething(id); }} /> ); };
额外说明
如果你的自定义端点符合API Platform规范,也可以将其加入Hydra文档,这样就能通过useDataProvider调用;但对于非CRUD的自定义端点,直接使用httpClient是更简洁的方案。
内容的提问来源于stack exchange,提问作者viko
相关产品推荐
相关产品推荐

