SpringBoot+React+OAuth2集成疑问:如何整合OAuth2AuthenticationToken
解决方案
一、Spring Boot 控制器与安全配置调整
你当前控制器用的@RestController会导致视图转发失效,需切换回@Controller。同时要结合Spring Security的OAuth2配置,强制用户完成Google认证后才能访问React页面。
1. 修正后的控制器代码
package com.logic.springbootwithreact.controllers; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class ClientForwardController { // 处理React前端路由转发,仅匹配非静态资源请求 @GetMapping(value = "/**/{path:[^.]*}") public String forwardToReact() { return "forward:/"; } // 可选:提供接口给React获取当前登录用户信息 @GetMapping("/api/user") public OAuth2User getCurrentUser(@AuthenticationPrincipal OAuth2User oAuth2User) { return oAuth2User; } }
2. Spring Security OAuth2配置
创建SecurityConfig类,配置Google登录与授权规则:
package com.logic.springbootwithreact.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain; @Configuration public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth // 允许匿名访问React打包后的静态资源 .requestMatchers("/static/**", "/js/**", "/css/**", "/index.html").permitAll() // 其余所有请求需认证 .anyRequest().authenticated() ) .oauth2Login(oauth2 -> oauth2 // 指定Google登录入口路径 .loginPage("/oauth2/authorization/google") ) .logout(logout -> logout // 退出登录后跳转回首页 .logoutSuccessUrl("/") .permitAll() ); return http.build(); } }
3. application.yml 配置(Google OAuth2客户端信息)
spring: security: oauth2: client: registration: google: client-id: 你的Google Client ID client-secret: 你的Google Client Secret scope: openid,email,profile
二、React App.js 实现
在React中判断用户认证状态,展示登录入口或用户信息/退出按钮,同时可调用后端接口获取用户数据:
import { useEffect, useState } from 'react'; function App() { const [user, setUser] = useState(null); // 页面加载时获取当前登录用户信息 useEffect(() => { fetch('/api/user') .then(response => { if (response.ok) return response.json(); setUser(null); }) .then(data => setUser(data)) .catch(err => console.error(err)); }, []); const handleLogin = () => { // 跳转到Spring Security的Google登录入口 window.location.href = '/oauth2/authorization/google'; }; const handleLogout = () => { // 跳转到Spring Security的退出接口 window.location.href = '/logout'; }; return ( <div className="App"> <header className="App-header"> {user ? ( <div> <h2>欢迎, {user.attributes.name}</h2> <p>邮箱: {user.attributes.email}</p> <button onClick={handleLogout}>退出登录</button> </div> ) : ( <button onClick={handleLogin}>使用Google登录</button> )} {/* 你的React路由组件内容 */} </header> </div> ); } export default App;
三、frontend-maven-plugin 配置要点
在pom.xml中配置插件,实现Spring Boot构建时自动打包React项目到static目录:
<build> <plugins> <plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> <version>1.14.0</version> <executions> <execution> <id>install node and npm</id> <goals> <goal>install-node-and-npm</goal> </goals> <configuration> <nodeVersion>v18.17.0</nodeVersion> <npmVersion>9.6.7</npmVersion> </configuration> </execution> <execution> <id>npm install</id> <goals> <goal>npm</goal> </goals> <configuration> <arguments>install</arguments> </configuration> </execution> <execution> <id>npm run build</id> <goals> <goal>npm</goal> </goals> <configuration> <arguments>run build</arguments> </configuration> </execution> </executions> <configuration> <!-- React项目根目录,根据实际路径调整 --> <workingDirectory>src/main/frontend</workingDirectory> <!-- 打包资源输出到Spring Boot的static目录 --> <installDirectory>target</installDirectory> </configuration> </plugin> </plugins> </build>
关键说明
- 需在Google Cloud Console中配置回调URL为
http://localhost:8080/login/oauth2/code/google(本地开发环境)。 - 前端路由转发规则
/**/{path:[^.]*}会匹配所有不带后缀的请求,转发到React首页,避免页面刷新时出现404。 - 静态资源需允许匿名访问,否则登录页面加载时会被拦截。
内容的提问来源于stack exchange,提问作者codeoak80
相关产品推荐
相关产品推荐

