如何实现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
相关产品推荐
相关产品推荐

