无法在 React 作为前端和 Spring 作为后端之间进行连接

问题描述 投票:0回答:1

我的 React 应用程序只是一个简单的登录页面,我的目的是如何通过 React Login 处理 Spring Security 身份验证,

我的 React 应用程序正在本地主机上运行:5713

我的 Spring 应用程序正在 localhost:5001 运行

我的反应代码:

export default function Login(){
    let [username,setUsername]=useState('')
    let [password,setPassword]=useState('')
    let formSubmit=async(e)=>{
        e.preventDefault();
        console.log(username,password)
        const login=await fetch("http://localhost:5001/login",{
            method: 'POST',
            headers:{
                'Content-Type':'application/json'
            },
            body:JSON.stringify({username,password})
        })
        console.log(login)

        const data=login.json();
        console.log(data)
    }

    // useEffect(()=>{

    // },[])


    return(
        <>
            <form onSubmit={formSubmit}>
                <label htmlFor="username">Name</label>
                <input id="username" name="username" type="text" value={username} onChange={e=>setUsername(e.target.value)} />
                <label htmlFor="password">Password</label>
                <input id="password" name="password" value={password} onChange={e=>setPassword(e.target.value)} type="password" />
                {/* <button type="submit">Login</button> */}
                <Button>Submit</Button> <!-- my custom button Component -->
            </form>
        </>
    )
}

这是我的 Spring Boot Security 的样子:

@EnableWebSecurity
public class SecurityConfigTest implements WebMvcConfigurer {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .securityMatcher("/**")
            .authorizeHttpRequests(authorize -> authorize
                .requestMatchers("/user/add", "/csrf", "/login").permitAll()
                .anyRequest().authenticated()
            )
            .formLogin(formLogin -> formLogin
                .loginPage("http://localhost:5173/login")  // My react app Login Form
                .defaultSuccessURL("/testing") //its defined in my Springboot controller
            )
            

        return http.build();
    }
@Bean
    UserDetailsService userDetailsService(PasswordEncoder pa) {
        UserDetails user=User.withUsername("admin")
                .password(pa.encode("pass"))
                .roles("ADMIN")
                .build();
        System.out.println("at userDetailsService");
        
        UserDetails user1=User.withUsername("user")
                .password(pa.encode("user"))
                .roles("USER")
                .build();
        
        
        System.out.println(user.getUsername());
        System.out.println(user.getPassword());
        return new InMemoryUserDetailsManager(user,user1);
    }

}

我在我的控制器类级别使用 @CrossOrigin(origins = "http://localhost:5173") 到我的 Spring Boot 应用程序中。

我的控制器:

@Controller
@CrossOrigin(origins = "http://localhost:5173")
class ConnTest{
    
    UserRepo userRepo;
    @Autowired
    TestingSerivce test;
    
//  one way to read the app.props values
    @Value("${spring.jpa.database}")
    String dbname;
    
    ConnTest(UserRepo userRepo,TestingSerivce test){
        this.userRepo=userRepo;
        this.test=test;
    }
    
    @ResponseBody
    @GetMapping("/")
    String test(HttpServletRequest req) {
        
        return "Hello Welcome to my Demo";
    }
    
    @ResponseBody
    @PostMapping("/user/add")
    int addUser(@RequestBody User user) {
        
        userRepo.save(user);
        System.out.println(user);
        
        return 1;
    }
    
    @ResponseBody
    @GetMapping("/out")
    String logoutHere(HttpServletRequest req) throws ServletException {
        System.out.println(req.getRemoteUser()+"\nSession : "+req.getSession());
        req.logout();
        HttpSession session = req.getSession(false);
        if(session!=null) session.invalidate();
        System.out.println(req.getRemoteUser()+"\nSession : "+req.getSession());
        
        return "Logging out...";
    }

    
    @ResponseBody
    @GetMapping("/csrf")
    CsrfToken httpServReq(HttpServletRequest req) {
//      return securityConfig.csrfToken(req);
        System.out.println("tesing");
        
        return (CsrfToken) req.getAttribute("_csrf");
        
    }
    
    @ResponseBody
    @GetMapping("/test/x")
    String testx(@RequestParam(required = false) String msg) {
        String header="{'ab':'xyx'}";
        byte []b=header.getBytes();
        
        String encoded=Base64.getEncoder().encodeToString(b);
        System.out.println(encoded);
        if (msg == null) {
            return "Null Msg";
        }
        return "this is my Testingx -> " + msg;
    }
    
    @ResponseBody
    @PostMapping("/login")
    UserDetails userLogin(@RequestBody UserDetail user) {
        System.out.println(user.getUsername()+"  --  "+user.getPassword());
        
        return user;
    }
    
}

问题:

每当我尝试访问 Spring Controller 中定义的任何安全路由(不要像这样使用它一样好)时,我都会成功获取 React 登录表单,但每当我提供凭据并点击“提交”按钮时,我都会得到Cors 错误,即使我在控制器类级别提到过它。

也无法重定向到 secureRoutes

当我对不安全的 URL 进行相同的尝试时,Cors 工作得很好,没有任何问题。所以我相信只有在使用安全路线时才会出现问题。

我在使用Spring Security Authentication时有什么错误吗?

Access to fetch at 'http://localhost:5001/login' from origin 'http://localhost:5173' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Login.jsx:14 
        
        
        POST http://localhost:5001/login net::ERR_FAILED
formSubmit @ Login.jsx:14
callCallback2 @ react-dom.development.js:4164
invokeGuardedCallbackDev @ react-dom.development.js:4213
invokeGuardedCallback @ react-dom.development.js:4277
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:4291
executeDispatch @ react-dom.development.js:9041
processDispatchQueueItemsInOrder @ react-dom.development.js:9073
processDispatchQueue @ react-dom.development.js:9086
dispatchEventsForPlugins @ react-dom.development.js:9097
(anonymous) @ react-dom.development.js:9288
batchedUpdates$1 @ react-dom.development.js:26179
batchedUpdates @ react-dom.development.js:3991
dispatchEventForPluginEventSystem @ react-dom.development.js:9287
dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ react-dom.development.js:6465
dispatchEvent @ react-dom.development.js:6457
dispatchDiscreteEvent @ react-dom.development.js:6430
Show 15 more frames
Show less
Login.jsx:14 
        
        
       
        
        Uncaught (in promise) TypeError: Failed to fetch
    at formSubmit (Login.jsx:14:27)
    at HTMLUnknownElement.callCallback2
reactjs spring-boot spring-security cors
1个回答
0
投票

您必须在 Springboot 应用程序中启用

CORS policy
。您可以使用以下方法来做到这一点:-

@CrossOrigin
public class ConnTest {
}

请参阅此答案以获取更多上下文: - 起源已被 CORS 策略 Spring boot 和 React 阻止

© www.soinside.com 2019 - 2024. All rights reserved.