简体   繁体   English

Spring 发送请求时启动错误 403

[英]Spring Boot error 403 when sending request

My system consists of 3 parts.我的系统由 3 个部分组成。 Spring Boot app, Angular app and Android app. Spring 启动应用程序、Angular 应用程序和 Android 应用程序。 When my Android app sends request to reset password (if don't remember it) then Spring Boot app receives this request with this method:当我的 Android 应用程序发送重置密码的请求(如果不记得)时,Spring 启动应用程序使用以下方法收到此请求:

@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";
}

where updateResetPasswordToken() is:其中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);
    }
}

where getUserDetailsByEmail() is:其中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;
}

and getUserByName() is: 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;
}

and setResetPasswordToken() is: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());
    }
}

Then user receives reset link on email.然后用户在 email 上收到复位链接。 He opens link which opens Angular app and I input on two EditText fields passsword twice and send with button send which performs this code:他打开了打开 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});
  }

What's strange this Angular's code generates OPTIONS request not POST why?这个 Angular 的代码生成 OPTIONS 请求而不是 POST 有什么奇怪的? Spring Boot app receives this request with method: Spring 启动应用程序通过以下方法接收此请求:

@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.";
}

But finally every time /reset_password comes then ERROR 403 shows up.但最后每次 /reset_password 出现时都会出现 ERROR 403。

I also added such class:我还添加了这样的 class:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

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

but it gives nothing.但它什么也没给。

What's wrong with this code?这段代码有什么问题?

Thank you very very very much for help!非常非常非常感谢您的帮助!

The issue is most likely with the preflight request that the angular app is sending.该问题很可能与 angular 应用程序发送的预检请求有关。 You could disable cors by adding this to your security configuration:您可以通过将其添加到您的安全配置中来禁用 cors:

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

or you can configure it to your use case by following the example from the spring documentation https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-cors-global-java或者您可以按照 spring 文档https://docs.spring.io/javacurrent.framework#mvc-cors-Z.io/javacurrent.framework#/docs-cors-Z.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM