You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在axios拦截器中使用@react-keycloak/web token触发Hook错误如何解决?

错误原因

你两次报错的核心原因都是违反了React Hook的调用规则:

  • React Hook只能在React函数组件的顶层或者自定义React Hook的顶层调用
  • 第一次你在普通JS模块的全局作用域直接调用useKeycloak,不属于上述允许的调用场景
  • 第二次封装的GetToken本质是自定义Hook,如果你依然在组件/Hook之外的场景(比如axios配置的全局代码里)调用它,还是会触发规则校验报错
正确实现方案

推荐两种常用的实现方式,按需选择即可:

方案1:直接导出初始化的keycloak实例使用(更推荐,配置更简单)

你项目中初始化@react-keycloak/web时,一定会提前创建keycloak实例再传给ReactKeycloakProvider,直接把这个实例单独导出,就可以在任意JS文件中直接调用,不需要走Hook获取。

第一步:抽离keycloak实例单独导出

创建src/keycloak.js文件存放初始化逻辑:

import Keycloak from 'keycloak-js';

// 替换为你自己的keycloak配置参数
const keycloak = new Keycloak({
  url: 'http://your-keycloak-domain/auth',
  realm: 'your-realm-name',
  clientId: 'your-client-id'
});

export default keycloak;

然后在项目入口文件(一般是src/index.js)中用这个实例初始化ReactKeycloakProvider即可,保持原有逻辑不变。

第二步:配置axios拦截器

直接导入上述导出的keycloak实例即可:

import axios from 'axios';
import keycloak from './keycloak';

const instance = axios.create({
  baseURL: 'https://example.com/api/v1/',
  timeout: 30000,
});

instance.interceptors.request.use(
  (config) => {
    // token存在时再挂载鉴权头,避免空值报错
    if (keycloak.token) {
      // 注意:标准JWT鉴权需要加Bearer前缀,后端一般会校验这个格式
      config.headers.Authorization = `Bearer ${keycloak.token}`;
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

export default instance;

后续直接导入这个axios实例发起请求即可,会自动携带最新的keycloak token。

方案2:封装自定义Hook返回axios实例

如果你需要在组件内部动态使用带token的axios实例,可以封装自定义Hook来实现:

import { useMemo } from 'react';
import axios from 'axios';
import { useKeycloak } from '@react-keycloak/web';

export const useAuthAxios = () => {
  const { keycloak } = useKeycloak();

  const axiosInstance = useMemo(() => {
    const instance = axios.create({
      baseURL: 'https://example.com/api/v1/',
      timeout: 30000,
    });

    instance.interceptors.request.use(
      (config) => {
        if (keycloak.token) {
          config.headers.Authorization = `Bearer ${keycloak.token}`;
        }
        return config;
      },
      (error) => Promise.reject(error)
    );

    return instance;
  // token更新时重新生成实例,保证携带的是最新token
  }, [keycloak.token]);

  return axiosInstance;
};

在组件内使用方式:

function TestComponent() {
  const authAxios = useAuthAxios();

  const fetchData = async () => {
    const res = await authAxios.get('/user/info');
    console.log(res.data);
  };

  return <button onClick={fetchData}>获取用户信息</button>;
}

内容的提问来源于stack exchange,提问作者Rygo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 07:06:08