密码验证无法验证

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

我正在尝试针对我的数据库创建一个简单的登录来验证用户。无论出于何种原因,当预期语句为 true 时,Bcrypt.checkpw 显示 false。我不知所措,为什么会这样。在过去的三天里我尝试了很多事情。例如,对于这些日志,我期望得到正确的匹配,但收到错误的结果。一切都在进行,直到我引入盐/哈希。

查看密码:9999999
对抗哈希:$2a$10$0ATPkyNqcXT8u3RTfoX7BuOzxuTvuNnVH5dgqjVc4agIKHglv7SAC
匹配结果:假
提供的用户名:UNIUSER
提供明文密码:9999999
密码检查失败。存储的密码哈希:
$2a$10$0ATPkyNqcXT8u3RTfoX7BuOzxuTvuNnVH5dgqjVc4agIKHglv7SAC

在我的用户模型中,我有以下相关部分;

public void hashAndSetPassword(String plaintextPassword) {
    int saltRounds = 10;
    this.passwordHash = BCrypt.hashpw(plaintextPassword, BCrypt.gensalt(saltRounds));
}

public boolean checkPassword(String password) {
    boolean isMatch = BCrypt.checkpw(password, passwordHash);
    System.out.println("Checking password: " + password);
    System.out.println("Against hash: " + passwordHash);
    System.out.println("Match result: " + isMatch);
    return isMatch;
}

在我的 UserController 中,我有以下内容。

@RestController
@RequestMapping("/users")
public class UserController {
    private final UserService userService;

@Autowired
public UserController(UserService userService) {
    this.userService = userService;
}

@PostMapping("/create")
public ResponseEntity<Map<String, Object>> createUser(@RequestBody User user) {
    // Take the plaintext password from the user input
    String plaintextPassword = user.getPasswordHash(); // Use getPasswordHash, not getPassword

    // Hash the password and set it in the User object
    user.hashAndSetPassword(plaintextPassword);

    User savedUser = userService.saveUser(user);

    Map<String, Object> response = new HashMap<>();
    response.put("message", "User created with ID: " + savedUser.getId());
    response.put("id", savedUser.getId());

    return ResponseEntity.ok(response);
}

private String generateSecureToken() {
    SecureRandom random = new SecureRandom();
    byte[] bytes = new byte[64];

    random.nextBytes(bytes);
    return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
}

@PostMapping("/login")
public ResponseEntity<Map<String, Object>> login(@RequestBody Map<String, String> credentials,
        HttpServletResponse response) {
    String username = credentials.get("username");
    String password = credentials.get("password");

    User user = userService.findByUsername(username);

    if (user != null) {
        String storedPasswordHash = user.getPasswordHash(); // Get the stored password hash from the database
        
        if (user.checkPassword(password)) { // Compare with hashed password
            String sessionToken = generateSecureToken();

            user.setSessionToken(sessionToken);

            userService.saveUser(user);

            Map<String, Object> responseMap = new HashMap<>();
            responseMap.put("message", "Login successful");
            responseMap.put("username", username);

            Cookie cookie = new Cookie("authToken", sessionToken);
            cookie.setMaxAge(3600);
            cookie.setPath("/"); // Site wide
            response.addCookie(cookie);

            return ResponseEntity.ok(responseMap);
        } else {
            Map<String, Object> responseMap = new HashMap<>();
            responseMap.put("message", "Login failed");
            System.out.println("Provided username: " + username);
            System.out.println("Provided plaintext password: " + password);
            System.out.println("Password check failed. Stored Password Hash: " + storedPasswordHash);
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(responseMap);
        }
    } else {
        Map<String, Object> responseMap = new HashMap<>();
        responseMap.put("message", "User not found");
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(responseMap);
    }
}

我在后端使用Java,在前端使用AngularJS。 JBcrypt 版本 0.4,带有 Maven 和 apache。我的数据库的 Oracle 数据库。任何有关此事的见解将不胜感激。 passwordHash 在数据库中存储为 VARCHAR2 (60),因为我之前有 255,但听说 60 可能有帮助。不过什么也没有。谢谢。

java bcrypt password-hash
1个回答
0
投票

无论谁将来遇到这个问题,利用 DTO 来促进该过程都可以解决问题。不太确定考虑面值的确切原因,所有东西都在前/后/DB之间正确携带,但请参阅下面的修复。

@RestController
@RequestMapping("/users")
public class UserController {
    private final UserService userService;

@Autowired
public UserController(UserService userService) {
    this.userService = userService;
}

@PostMapping("/create")
public ResponseEntity<Map<String, Object>> createUser(@RequestBody RegistrationDTO registration) {
    User user = new User();
    user.setUsername(registration.getUsername());
    user.setFirstName(registration.getFirstName());
    user.setLastName(registration.getLastName());
    user.setTelephone(registration.getTelephone());
    user.setAddress(registration.getAddress());
    user.setCity(registration.getCity());
    user.setPostalCode(registration.getPostalCode());
    user.setCountry(registration.getCountry());

    user.hashAndSetPassword(registration.getPassword());

    User savedUser = userService.saveUser(user);

    Map<String, Object> response = new HashMap<>();
    response.put("message", "User created with ID: " + savedUser.getId());
    response.put("id", savedUser.getId());

    return ResponseEntity.ok(response);
}

private String generateSecureToken() {
    SecureRandom random = new SecureRandom();
    byte[] bytes = new byte[64];

    random.nextBytes(bytes);
    return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
}

@PostMapping("/login")
public ResponseEntity<Map<String, Object>> login(@RequestBody LoginDTO loginDTO, HttpServletResponse response) {
    String username = loginDTO.getUsername();
    String password = loginDTO.getPassword();
    User user = userService.findByUsername(username);

    if (user != null) {

        if (user.checkPassword(password)) { 
            String sessionToken = generateSecureToken();

            user.setSessionToken(sessionToken);

            userService.saveUser(user);

            Map<String, Object> responseMap = new HashMap<>();
            responseMap.put("message", "Login successful");
            responseMap.put("username", username);

            Cookie cookie = new Cookie("authToken", sessionToken);
            cookie.setMaxAge(3600);
            cookie.setPath("/"); // Site wide
            response.addCookie(cookie);

            return ResponseEntity.ok(responseMap);
        } else {
            Map<String, Object> responseMap = new HashMap<>();
            responseMap.put("message", "Login failed");
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(responseMap);
        }
    } else {
        Map<String, Object> responseMap = new HashMap<>();
        responseMap.put("message", "User not found");
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(responseMap);
    }
}

}

然后是两个简单的 DTO,例如;

public class RegistrationDTO {

private String username;
private String password;
private String firstName;
private String lastName;
private String telephone;
private String address;
private String city;
private String postalCode;
private String country;

// Getters
public String getUsername() {
    return username;
}

public String getPassword() {
    return password;
}

public String getFirstName() {
    return firstName;
}

public String getLastName() {
    return lastName;
}

public String getTelephone() {
    return telephone;
}

public String getAddress() {
    return address;
}

public String getCity() {
    return city;
}

public String getPostalCode() {
    return postalCode;
}

public String getCountry() {
    return country;
}

// Setters
public void setUsername(String username) {
    this.username = username;
}

public void setPassword(String password) {
    this.password = password;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

public void setLastName(String lastName) {
    this.lastName = lastName;
}

public void setTelephone(String telephone) {
    this.telephone = telephone;
}

public void setAddress(String address) {
    this.address = address;
}

public void setCity(String city) {
    this.city = city;
}

public void setPostalCode(String postalCode) {
    this.postalCode = postalCode;
}

public void setCountry(String country) {
    this.country = country;
}

}

和登录DTO;

public class LoginDTO {

private String username;
private String password;

// Getters
public String getUsername() {
    return username;
}

public String getPassword() {
    return password;
}

// Setters
public void setUsername(String username) {
    this.username = username;
}

public void setPassword(String password) {
    this.password = password;
}

}

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