发送请求时 Spring Boot 错误 403

Posted

技术标签:

【中文标题】发送请求时 Spring Boot 错误 403【英文标题】:Spring Boot error 403 when sending request 【发布时间】:2022-01-10 17:28:50 【问题描述】:

我的系统由 3 个部分组成。 Spring Boot 应用、Angular 应用和 android 应用。当我的 Android 应用发送重置密码的请求时(如果不记得),Spring Boot 应用会使用以下方法接收此请求:

@PostMapping("/forgot_password")
public String processForgotPassword(@RequestBody String email, HttpServletRequest request) 
    try 
        String token = RandomString.make(30);
        userService.updateResetPasswordToken(token, email);
        String resetPasswordLink = "https://jakuwegiel.web.app/projects/endless-blow/reset-password?token=" + token;
        sendEmail(email, resetPasswordLink);

     catch (Exception ex) 
        System.out.println(ex.getMessage());
    
    return "Email has been sent";

updateResetPasswordToken() 在哪里:

public void updateResetPasswordToken(String token, String email) throws SQLException 
    UserDetails userDetails = usersDao.getUserDetailsByEmail(connFromUserService, email);
    if (userDetails != null) 
        User user = usersDao.getUserByName(connFromUserService, userDetails.getName());
        usersDao.setResetPasswordToken(connFromUserService, user, token);
    

getUserDetailsByEmail() 在哪里:

public UserDetails getUserDetailsByEmail(Connection connection, String email) 
    UserDetails userDetails = new UserDetails();
    PreparedStatement ps;
    try 
        ps = connection.prepareStatement("SELECT * from users_details where email = '"+email+"'");
        ResultSet rs = ps.executeQuery();
        if (rs.next()) 
            userDetails = new UserDetails(rs.getString(2), rs.getString(3));
        
     catch (SQLException e) 
        e.printStackTrace();
    
    return userDetails;

getUserByName() 是:

public User getUserByName(Connection connection, String name) throws SQLException 
    User user = new User();
    PreparedStatement ps;
    try 
        ps = connection.prepareStatement("SELECT * from users where username = '"+name+"'");
        ResultSet rs = ps.executeQuery();
        if (rs.next()) 
            user = new User(rs.getString(2), rs.getString(3));
        
     catch (SQLException e) 
        e.printStackTrace();
    
    return user;

setResetPasswordToken() 是:

public void setResetPasswordToken(Connection connection, User user, String token) 
    PreparedStatement ps;
    try 
        ps = connection.prepareStatement("UPDATE users set reset_password_token = '" + token + "' where username = '" + user.getUsername() + "'");
        ps.executeUpdate();
     catch (SQLException e) 
        System.out.println(e.getMessage());
    

然后用户在电子邮件中收到重置链接。他打开了打开 Angular 应用程序的链接,我在两个 EditText 字段上输入了两次密码,然后使用执行此代码的按钮发送:

  public postResetPassword(token: string, password: string): Observable<any> 
    const body = 
      'token': token,
      'password': password
    ;
    const headers = new HttpHeaders().set('Content-Type', 'application/json; charset=utf-8');
    return this.http.post<any>('https://endlessblow-1.herokuapp.com/reset_password', body,headers: headers);
  

这个 Angular 的代码生成 OPTIONS 请求而不是 POST 有什么奇怪的? Spring Boot 应用程序通过方法接收此请求:

@RequestMapping(value = "/reset_password", consumes="application/json", method = RequestMethod.OPTIONS, RequestMethod.POST, RequestMethod.GET)
public String processResetPassword(@RequestBody TokenAndPassword tokenAndPassword) 
    try 
        User user = userService.getByResetPasswordToken(tokenAndPassword.getToken());
        if (user == null) 
            return "message1";
         else 
            userService.updatePassword(user, tokenAndPassword.getPassword());
            System.out.println("You have successfully changed your password.");
        
    
    catch (Exception ex) 
        System.out.println(ex.getMessage());
        return "Error. Did you use your token already? Or does this link come from email?";
    

    return "You have successfully changed your password.";

但最后每次 /reset_password 出现时都会出现 ERROR 403。

我也添加了这样的类:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter 

@Override
public void configure(HttpSecurity http) throws Exception 
    http
            .csrf().disable()
            .authorizeRequests().anyRequest().permitAll();


但它什么也没给。

这段代码有什么问题?

非常非常非常感谢您的帮助!

【问题讨论】:

【参考方案1】:

问题很可能与 Angular 应用程序发送的预检请求有关。您可以通过将其添加到您的安全配置来禁用 cors:

@Override
public void addCorsMappings(CorsRegistry registry) 
    registry.addMapping("/**").allowedMethods("*");

或者您可以按照 Spring 文档 https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-cors-global-java 中的示例将其配置到您的用例中

【讨论】:

好吧,我明天去看看。请继续关注这个话题好吗?如果结果证明有效,我会将这个答案标记为已接受,现在你保留一个喜欢:)

以上是关于发送请求时 Spring Boot 错误 403的主要内容,如果未能解决你的问题,请参考以下文章

发送 post 请求时出现 CORS 错误,但在 Spring Boot 和 Reactjs 中未获取请求

Spring boot 错误处理机制

如何处理 Spring Boot、AngularJS 应用程序中的 CORS 错误?

在 Spring Boot 中从 Angular 向后端发送 post 请求中的对象的问题

Spring Boot 中禁止 OPTIONS 请求

使用邮递员发布请求后,spring boot 服务器返回错误 400