Java案例怎么实现登录认证?

wen java案例 18

本文目录导读:

Java案例怎么实现登录认证?

  1. 最基础:基于 Session 的简单认证(Servlet/JSP)
  2. 前后端分离:基于 Token(JWT)的认证
  3. 企业级标准:Spring Security + JWT
  4. 选择建议
  5. 关键安全注意事项
  6. 完整示例代码结构

在Java中实现登录认证,根据项目规模和复杂度,有多种实现方式,以下从基础原理企业级框架,分层次介绍几种典型的实现案例。


最基础:基于 Session 的简单认证(Servlet/JSP)

这是最原始的方式,适用于理解认证核心流程。

核心原理

  1. 用户提交用户名和密码
  2. 服务器验证凭据
  3. 验证成功,将用户信息存入 HttpSession
  4. 后续请求检查 Session 中是否有用户信息

代码示例

LoginServlet.java

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        // 硬编码校验(实际应查询数据库)
        if ("admin".equals(username) && "123456".equals(password)) {
            // 登录成功,存入 Session
            HttpSession session = req.getSession();
            session.setAttribute("user", username);
            resp.sendRedirect("/home.jsp");
        } else {
            req.setAttribute("error", "用户名或密码错误");
            req.getRequestDispatcher("/login.jsp").forward(req, resp);
        }
    }
}

AuthFilter.java(拦截器保护资源)

@WebFilter("/home.jsp")
public class AuthFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpSession session = req.getSession(false);
        if (session == null || session.getAttribute("user") == null) {
            req.setAttribute("error", "请先登录");
            req.getRequestDispatcher("/login.jsp").forward(request, response);
        } else {
            chain.doFilter(request, response); // 放行
        }
    }
}

特点:简单直接,但不适用于分布式/前后端分离,Session 依赖服务器内存。


前后端分离:基于 Token(JWT)的认证

现代 Web 应用(Vue/React + Spring Boot)最常用。

核心流程

  1. 用户登录 → 服务端验证 → 签发 JWT
  2. 前端将 JWT 存在 localStoragecookie
  3. 每次请求在 Authorization 头携带 JWT
  4. 过滤器解析 JWT,提取用户信息放入安全上下文

Java 案例(Spring Boot + JJWT)

添加依赖(Maven)

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.12.5</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.12.5</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.12.5</version>
    <scope>runtime</scope>
</dependency>

JWT 工具类

public class JwtUtil {
    private static final String SECRET = "your-256-bit-secret-key-change-in-production";
    private static final long EXPIRATION = 86400000L; // 24小时
    // 生成 Token
    public static String generateToken(String username) {
        return Jwts.builder()
                .subject(username)
                .issuedAt(new Date())
                .expiration(new Date(System.currentTimeMillis() + EXPIRATION))
                .signWith(SignatureAlgorithm.HS256, SECRET)
                .compact();
    }
    // 解析 Token
    public static String parseToken(String token) {
        return Jwts.parser()
                .setSigningKey(SECRET)
                .build()
                .parseClaimsJws(token)
                .getBody()
                .getSubject();
    }
    // 验证 Token 有效性
    public static boolean isValid(String token) {
        try {
            parseToken(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

登录接口

@PostMapping("/api/login")
public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
    // 1. 验证用户名密码(查询数据库,这里简单模拟)
    if ("admin".equals(loginRequest.getUsername()) && "123456".equals(loginRequest.getPassword())) {
        // 2. 生成 JWT
        String token = JwtUtil.generateToken(loginRequest.getUsername());
        // 3. 返回 Token
        return ResponseEntity.ok(new JwtResponse(token, "登录成功"));
    }
    return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("用户名或密码错误");
}

JWT 过滤器(Spring Security 方式见下节)

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, 
                                    FilterChain filterChain) throws ServletException, IOException {
        String authHeader = request.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            String token = authHeader.substring(7);
            if (JwtUtil.isValid(token)) {
                String username = JwtUtil.parseToken(token);
                // 将用户信息放入 SecurityContext(用于后续控制器获取)
                UsernamePasswordAuthenticationToken authentication = 
                    new UsernamePasswordAuthenticationToken(username, null, null);
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }
        filterChain.doFilter(request, response);
    }
}

前端配合(Vue/React 示例)

// 登录成功后存储 Token
localStorage.setItem('token', response.data.token);
// Axios 拦截器自动携带 Token
axios.interceptors.request.use(config => {
    const token = localStorage.getItem('token');
    if (token) {
        config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
});

特点:无状态、分布式友好、前后端解耦。


企业级标准:Spring Security + JWT

Spring Security 提供了完整的认证授权框架,学习曲线略高,但功能强大。

核心配置

SecurityConfig.java

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable()) // 前后端分离需关闭 CSRF
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // 无状态
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/login", "/api/register").permitAll()
                .anyRequest().authenticated()
            )
            .addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(); // 密码加密
    }
    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter() {
        return new JwtAuthenticationFilter();
    }
}

UserDetailsService 实现(数据库查用户)

@Service
public class CustomUserDetailsService implements UserDetailsService {
    @Autowired
    private UserRepository userRepository;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username)
                .orElseThrow(() -> new UsernameNotFoundException("用户不存在"));
        return new org.springframework.security.core.userdetails.User(
            user.getUsername(),
            user.getPassword(),
            user.getRoles().stream()
                .map(role -> new SimpleGrantedAuthority(role.getName()))
                .collect(Collectors.toList())
        );
    }
}

登录接口(使用 AuthenticationManager)

@RestController
public class AuthController {
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private JwtUtil jwtUtil;
    @PostMapping("/api/login")
    public ResponseEntity<?> login(@RequestBody LoginRequest request) {
        Authentication authentication = authenticationManager.authenticate(
            new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword())
        );
        // 认证成功,生成 Token
        String token = jwtUtil.generateToken(authentication.getName());
        return ResponseEntity.ok(new JwtResponse(token));
    }
}

选择建议

场景 推荐方案 原因
单体应用、课后作业 Session 认证 简单,无需额外依赖
前后端分离、Vue/React+Spring Boot JWT 自定义过滤器 轻量,足够用
大型企业项目、多角色/权限复杂 Spring Security + JWT 标准、可扩展、社区支持好
微服务架构 OAuth2 + JWT + Spring Security 统一认证中心

关键安全注意事项

  1. 密码存储:永远不要明文存储密码,使用 BCryptArgon2 等密码哈希算法。
  2. HTTPS:生产环境必须使用 HTTPS,防止 Token 被中间人窃取。
  3. JWT 过期:设置合理的过期时间(建议 15-30 分钟),配合 Refresh Token 实现长期登录。
  4. XSS/CSRF:Token 不要放在容易被注入的 localStorage(可放 HttpOnly Cookie 配合 CSRF Token)。
  5. 权限校验:不仅是登录认证,每个接口还需要检查用户是否拥有对应操作权限(RBAC)。

完整示例代码结构

project/
├── config/
│   └── SecurityConfig.java        // Spring Security 配置
├── filter/
│   └── JwtAuthenticationFilter.java
├── util/
│   └── JwtUtil.java               // JWT 工具类
├── controller/
│   └── AuthController.java        // 登录/注册接口
├── service/
│   ├── UserService.java
│   └── CustomUserDetailsService.java
├── model/
│   └── User.java
└── repository/
    └── UserRepository.java

如果你有具体的项目框架需求(Spring Boot + Vue 的完整项目),我可以进一步给出更详细的实现代码。

抱歉,评论功能暂时关闭!