本文目录导读:

- 最基础:基于 Session 的简单认证(Servlet/JSP)
- 前后端分离:基于 Token(JWT)的认证
- 企业级标准:Spring Security + JWT
- 选择建议
- 关键安全注意事项
- 完整示例代码结构
在Java中实现登录认证,根据项目规模和复杂度,有多种实现方式,以下从基础原理到企业级框架,分层次介绍几种典型的实现案例。
最基础:基于 Session 的简单认证(Servlet/JSP)
这是最原始的方式,适用于理解认证核心流程。
核心原理
- 用户提交用户名和密码
- 服务器验证凭据
- 验证成功,将用户信息存入
HttpSession - 后续请求检查
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)最常用。
核心流程
- 用户登录 → 服务端验证 → 签发 JWT
- 前端将 JWT 存在
localStorage或cookie中 - 每次请求在
Authorization头携带 JWT - 过滤器解析 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 | 统一认证中心 |
关键安全注意事项
- 密码存储:永远不要明文存储密码,使用
BCrypt、Argon2等密码哈希算法。 - HTTPS:生产环境必须使用 HTTPS,防止 Token 被中间人窃取。
- JWT 过期:设置合理的过期时间(建议 15-30 分钟),配合 Refresh Token 实现长期登录。
- XSS/CSRF:Token 不要放在容易被注入的 localStorage(可放 HttpOnly Cookie 配合 CSRF Token)。
- 权限校验:不仅是登录认证,每个接口还需要检查用户是否拥有对应操作权限(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 的完整项目),我可以进一步给出更详细的实现代码。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播