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

如何实现React前端访问Keycloak认证的Spring Boot后端数据

实现方案指导

一、React集成Keycloak获取访问令牌

直接用官方的keycloak-js包完成前端的Keycloak集成,步骤如下:

  • 安装依赖:
    npm install keycloak-js
    
  • 新建Keycloak初始化文件(比如src/utils/keycloak.js):
    import Keycloak from 'keycloak-js';
    
    // 替换成你的Keycloak实际配置
    const keycloak = new Keycloak({
      url: 'http://localhost:8080/auth',
      realm: '你的Realm名称',
      clientId: 'React前端对应的Client ID'
    });
    
    export default keycloak;
    
  • 在App入口初始化Keycloak,确保登录完成后再渲染页面:
    import keycloak from './utils/keycloak';
    import { useEffect, useState } from 'react';
    
    function App() {
      const [isLoggedIn, setIsLoggedIn] = useState(false);
    
      useEffect(() => {
        keycloak.init({ onLoad: 'login-required' })
          .then(authStatus => {
            setIsLoggedIn(authStatus);
            // 定时刷新令牌,避免过期
            setInterval(() => {
              keycloak.updateToken(70).catch(() => keycloak.login());
            }, 60000);
          })
          .catch(err => console.error('Keycloak初始化失败:', err));
      }, []);
    
      if (!isLoggedIn) {
        return <div>登录中...</div>;
      }
    
      return (
        // 你的应用组件内容
      );
    }
    
    export default App;
    

二、配置前端代理解决跨域

因为前端跑在localhost:3000,后端在localhost:8081,直接请求会触发跨域限制,用React代理转发请求:

  • 在项目根目录创建setupProxy.js(和package.json同级):
    const { createProxyMiddleware } = require('http-proxy-middleware');
    
    module.exports = function(app) {
      app.use(
        '/products',
        createProxyMiddleware({
          target: 'http://localhost:8081',
          changeOrigin: true,
        })
      );
    };
    

配置后,前端请求/products会自动转发到http://localhost:8081/products。

三、携带令牌调用后端接口

登录成功后,从Keycloak实例中拿访问令牌,在请求头里带上Authorization: Bearer {token}:

  • 新建API调用文件(比如src/services/api.js):
    import keycloak from '../utils/keycloak';
    
    export async function fetchProducts() {
      try {
        const token = keycloak.token;
        const res = await fetch('/products', {
          method: 'GET',
          headers: {
            'Authorization': `Bearer ${token}`,
            'Content-Type': 'application/json'
          }
        });
    
        if (!res.ok) {
          throw new Error(`请求失败: ${res.status}`);
        }
    
        return await res.json();
      } catch (err) {
        console.error('获取产品数据失败:', err);
        // 遇到401未授权时,跳转回登录页
        if (err.message.includes('401')) {
          keycloak.login();
        }
        throw err;
      }
    }
    
  • 在组件中调用这个接口:
    import { useEffect, useState } from 'react';
    import { fetchProducts } from './services/api';
    
    function ProductsPage() {
      const [products, setProducts] = useState([]);
    
      useEffect(() => {
        async function getProductList() {
          try {
            const data = await fetchProducts();
            setProducts(data);
          } catch (err) {
            // 自定义错误处理逻辑
          }
        }
        getProductList();
      }, []);
    
      return (
        <div>
          <h2>产品列表</h2>
          <ul>
            {products.map(item => (
              <li key={item.id}>{item.name}</li>
            ))}
          </ul>
        </div>
      );
    }
    
    export default ProductsPage;
    

四、关键配置检查

  • Keycloak客户端:确保React对应的Client的Access Type设为public(单页应用无法保存密钥),Valid Redirect URIs添加http://localhost:3000/*,Web Origins设为http://localhost:3000。
  • Spring Boot后端:确认Keycloak Realm、客户端配置正确,且/products接口已配置安全规则(比如用@PreAuthorize("isAuthenticated()")或SecurityFilterChain)允许已认证用户访问。

五、调试要点

  • 用浏览器开发者工具的Network标签,查看/products请求的请求头,确认Authorization字段是否携带了正确的令牌。
  • 若出现401错误,可解码JWT令牌(用浏览器atob解码token的payload部分),检查issuer、audience是否与后端配置匹配。
  • 代理不生效时,重启React开发服务器,确认setupProxy.js配置无误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 07:25:20