You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android登录认证对接Spring Boot服务器登录失败问题求助

Hey Paolo, let's troubleshoot your login issue step by step—since your register flow works, we already know your password encoding and user persistence are on the right track. Let's break down the most common pitfalls and fixes for your Spring Boot login endpoint:

1. First, Fix the Incomplete Login Implementation

Your provided login code snippet cuts off, so let's start with a proper custom login endpoint example that aligns with your working register logic:

// First, create a simple DTO for login requests (since you don't need all Person fields)
public class LoginRequest {
    private String username;
    private String password;
    // Getters and setters
}

// Then complete your login endpoint
@PostMapping("/login")
public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {
    // 1. Fetch the user from your database using the username
    Person user = userService.findByUsername(loginRequest.getUsername());
    
    // 2. Check if user exists
    if (user == null) {
        return ResponseEntity.badRequest().body("User not found");
    }
    
    // 3. Verify the password with the SAME encoder you used for registration
    if (!encoder.matches(loginRequest.getPassword(), user.getPassword())) {
        return ResponseEntity.badRequest().body("Invalid password");
    }
    
    // 4. Return authentication details (e.g., JWT token if you're using it)
    // Example: String jwtToken = jwtGenerator.generateToken(user.getUsername());
    return ResponseEntity.ok("Login successful!");
}

Critical note: Always use the exact PasswordEncoder bean you injected for registration—never instantiate a new one in the login method, as BCrypt uses a random salt each time, which will break password matching.

2. Check Your Spring Security Configuration

If you're using Spring Security (which is standard for auth flows), make sure your config isn't blocking the login endpoint or misconfigured:

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    private final UserDetailsService userDetailsService;
    private final PasswordEncoder passwordEncoder;

    // Constructor injection (preferred over @Autowired)
    public SecurityConfig(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
        this.userDetailsService = userDetailsService;
        this.passwordEncoder = passwordEncoder;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable()) // Disable CSRF for API-only flows (Android app is a client)
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/register", "/login").permitAll() // Allow public access to auth endpoints
                .anyRequest().authenticated() // Secure all other endpoints
            );
        return http.build();
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }
}

Without this, your login request might get blocked by Spring Security's default authentication filter before it even reaches your custom endpoint.

3. Verify Frontend Request Format

Since your register endpoint uses @RequestBody Person user, your Android app must send login data as JSON (not form-data or x-www-form-urlencoded). Double-check that your app's login request body looks like this:

{
  "username": "your-username",
  "password": "your-plain-text-password"
}

If the format is wrong, your backend won't parse the request correctly, leading to empty username/password values during authentication.

4. Validate Your Person Class (If Using UserDetails)

If your Person class implements Spring's UserDetails interface, ensure these methods return true (unless you have custom account locking logic):

@Override
public boolean isAccountNonExpired() {
    return true;
}

@Override
public boolean isAccountNonLocked() {
    return true;
}

@Override
public boolean isCredentialsNonExpired() {
    return true;
}

@Override
public boolean isEnabled() {
    return true;
}

Spring Security will reject login attempts if any of these flags are false.

Quick Debugging Tip

Add logging to your login endpoint to see exactly what's failing:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

private static final Logger log = LoggerFactory.getLogger(YourAuthController.class);

@PostMapping("/login")
public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {
    log.info("Attempting login for username: {}", loginRequest.getUsername());
    
    Person user = userService.findByUsername(loginRequest.getUsername());
    if (user == null) {
        log.warn("No user found with username: {}", loginRequest.getUsername());
        return ResponseEntity.badRequest().body("User not found");
    }
    
    if (!encoder.matches(loginRequest.getPassword(), user.getPassword())) {
        log.warn("Invalid password for username: {}", loginRequest.getUsername());
        return ResponseEntity.badRequest().body("Invalid password");
    }
    
    return ResponseEntity.ok("Login successful!");
}

Check your backend logs to see if the issue is a missing user, mismatched password, or something else entirely.

内容的提问来源于stack exchange,提问作者PaoloPaul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:42:48