导读:本期聚焦于小伙伴创作的《React前端如何对接Spring Security处理跨域登录POST请求?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《React前端如何对接Spring Security处理跨域登录POST请求?》有用,将其分享出去将是对创作者最好的鼓励。

React前端如何对接Spring Security处理跨域登录POST请求?

一、问题背景

前后端分离架构下,React前端通常运行在3000端口,Spring Security后端运行在8080端口,端口不同属于跨域场景。当React发起登录POST请求时,浏览器会先发送OPTIONS预检请求,如果后端没有正确配置跨域规则,或者Spring Security的安全拦截规则没有放行登录接口,就会导致登录请求失败。同时POST请求的参数格式、登录成功后的状态保持也是需要重点处理的部分。

二、Spring Security后端配置

2.1 跨域配置类

首先需要在后端配置跨域规则,允许前端域名的请求,同时处理预检请求:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        // 允许前端React运行的域名,实际开发替换为真实前端地址
        config.addAllowedOrigin("http://localhost:3000");
        // 允许携带凭证(cookie等)
        config.setAllowCredentials(true);
        // 允许所有请求方法
        config.addAllowedMethod("*");
        // 允许所有请求头
        config.addAllowedHeader("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        // 对所有接口生效
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

2.2 Spring Security安全规则配置

需要放行登录接口,同时配置登录成功、失败的处理逻辑,避免默认跳转导致跨域问题:

import com.fasterxml.jackson.databind.ObjectMapper;
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.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .cors() // 开启跨域支持,关联上面的CorsFilter
            .and()
            .csrf().disable() // 前后端分离场景关闭csrf,避免POST请求被拦截
            .authorizeRequests()
            .antMatchers("/login").permitAll() // 放行登录接口
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .loginProcessingUrl("/login") // 登录接口地址
            .successHandler(successHandler()) // 登录成功处理
            .failureHandler(failureHandler()); // 登录失败处理
    }

    // 登录成功返回JSON,避免默认跳转
    @Bean
    public AuthenticationSuccessHandler successHandler() {
        return (request, response, authentication) -> {
            response.setContentType("application/json;charset=UTF-8");
            Map<String, Object> result = new HashMap<>();
            result.put("code", 200);
            result.put("msg", "登录成功");
            result.put("data", authentication.getPrincipal());
            new ObjectMapper().writeValue(response.getWriter(), result);
        };
    }

    // 登录失败返回JSON
    @Bean
    public AuthenticationFailureHandler failureHandler() {
        return (request, response, exception) -> {
            response.setContentType("application/json;charset=UTF-8");
            Map<String, Object> result = new HashMap<>();
            result.put("code", 401);
            result.put("msg", "登录失败:" + exception.getMessage());
            new ObjectMapper().writeValue(response.getWriter(), result);
        };
    }
}

三、React前端请求实现

3.1 封装登录请求方法

React前端需要使用fetch或者axios发送POST请求,注意要携带凭证,参数格式要符合Spring Security的表单登录要求:

// 使用fetch发送登录请求
const login = async (username, password) => {
    const formData = new URLSearchParams();
    formData.append("username", username);
    formData.append("password", password);
    try {
        const response = await fetch("http://localhost:8080/login", {
            method: "POST",
            // 携带凭证,保证登录后cookie能正常传递
            credentials: "include",
            headers: {
                "Content-Type": "application/x-www-form-urlencoded"
            },
            body: formData.toString()
        });
        const result = await response.json();
        if (result.code === 200) {
            // 登录成功,存储登录状态
            localStorage.setItem("isLogin", "true");
            console.log("登录成功", result.data);
        } else {
            console.log("登录失败", result.msg);
        }
    } catch (error) {
        console.error("请求出错", error);
    }
};

// 调用登录方法
// login("admin", "123456");

3.2 登录组件示例

简单的登录表单组件,收集用户输入调用登录方法:

import React, { useState } from "react";

const LoginForm = () => {
    const [username, setUsername] = useState("");
    const [password, setPassword] = useState("");

    const handleSubmit = (e) => {
        e.preventDefault();
        // 调用上面的login方法
        login(username, password);
    };

    return (
        <form onSubmit={handleSubmit}>
            <div>
                <label>用户名:</label>
                <input
                    type="text"
                    value={username}
                    onChange={(e) => setUsername(e.target.value)}
                />
            </div>
            <div>
                <label>密码:</label>
                <input
                    type="password"
                    value={password}
                    onChange={(e) => setPassword(e.target.value)}
                />
            </div>
            <button type="submit">登录</button>
        </form>
    );
};

export default LoginForm;

四、常见问题与解决

  • 预检请求失败:检查后端跨域配置是否允许前端域名,是否开启了cors()配置,预检请求的方法、头是否被允许。
  • 登录请求被403拦截:确认Spring Security中是否放行了/login接口,是否关闭了csrf,或者csrf规则是否适配前后端分离场景。
  • 登录后状态无法保持:前端请求必须设置credentials: "include",后端跨域配置必须设置setAllowCredentials(true),否则cookie无法传递。
  • 参数接收不到:Spring Security表单登录默认接收usernamepassword字段,前端参数名要匹配,且Content-Type要使用application/x-www-form-urlencoded

ReactSpring_Security跨域请求POST登录前后端分离修改时间:2026-05-30 23:44:19

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。