一、需求分析
在开发一个安全性要求较高的系统时,用户身份的验证是基础模块之一。登录校验模块的主要功能包括:
-
验证用户身份:用户提供的用户名和密码需要与系统存储的记录进行匹配。
-
生成认证令牌:在身份验证成功后,生成唯一的 JWT(JSON Web Token)令牌,供客户端在后续请求中携带,用于身份识别。
-
错误处理:如果验证失败,需要清晰地返回错误提示。
二、代码解读
JWT 工具类
java
public class JwtUtils {
private static String signKey = "SVRIRUlNQQ==";
private static Long expire = 43200000L; //12 hours;
public static String generateJwt(Map<String,Object> claims){
String jwt = Jwts.builder()
.addClaims(claims)
.signWith(SignatureAlgorithm.HS256, signKey)
.setExpiration(new Date(System.currentTimeMillis() + expire))
.compact();
return jwt;
}
public static Claims parseJWT(String jwt){
Claims claims = Jwts.parser()
.setSigningKey(signKey)
.parseClaimsJws(jwt)
.getBody();
return claims;
}
}
逻辑说明:
-
JWT 生成:
-
generateJwt方法接收一个包含用户信息的Map。 -
使用 JJWT 库的
Jwts.builder()构造 JWT,采用 HS256 算法签名,并设置过期时间。 -
生成的 JWT 是一个字符串,供客户端后续请求时使用。
-
-
JWT 解析:
-
parseJWT方法接收客户端传递的 JWT 字符串。 -
通过验证签名密钥解析出原始负载数据
Claims。
-
登录信息类(LoginInfo)
java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class LoginInfo {
private Integer id;
private String username;
private String name;
private String token;
}
逻辑说明:
-
@Data:由 Lombok 提供,自动生成 getter、setter、toString、equals 和 hashCode 方法。 -
@AllArgsConstructor:生成带所有字段参数的构造方法。 -
@NoArgsConstructor:生成无参数构造方法。 -
类的字段包括用户 ID、用户名、真实姓名以及 JWT 令牌,用于登录成功后返回给客户端。
控制层(Controller)
java
@RestController
@RequestMapping("/login")
@Slf4j
public class LoginController {
@Autowired
private EmpService empService;
@PostMapping
public Result login(@RequestBody Emp emp){
log.info("用户登录:{}", emp.getUsername());
LoginInfo info = empService.testIdandPassword(emp);
if(info != null) return Result.success(info);
return Result.error("账号或密码错误!请重新输入!");
}
}
逻辑说明:
-
@RestController:使用@RestController(本质上是@Controller和@ResponseBody的结合),可以让方法的返回值直接序列化为 JSON 格式,并通过 HTTP 响应体返回到客户端。这样非常适合 RESTful 风格的 API 开发。 -
@RequestMapping("/login"):将此控制器的所有接口路径映射到/login。 -
@PostMapping:定义了一个 POST 请求的处理方法。 -
@RequestBody:将请求体中的 JSON 数据解析为Emp对象。 -
日志记录:
log.info用于记录用户尝试登录的用户名。 -
调用
empService.testIdandPassword(emp)检查用户身份。 -
如果验证成功,返回带有用户信息和 JWT 的
Result.success;否则返回错误信息。
服务层(Service)
java
@Override
public LoginInfo testIdandPassword(Emp emp) {
Emp e = empMapper.testIdandPassword(emp);
Map<String, Object> map = new HashMap<>();
map.put("name", e.getName());
map.put("userName", e.getUsername());
map.put("id", e.getId());
if(e != null) return new LoginInfo(e.getId(), e.getUsername(), e.getName(), JwtUtils.generateJwt(map));
return null;
}
逻辑说明:
-
调用
empMapper.testIdandPassword(emp)查询数据库,验证用户名和密码是否匹配。 -
如果查询结果非空,将用户信息(如
id、username、name)存入一个Map中,生成 JWT。 -
返回一个包含用户信息和生成的 JWT 的
LoginInfo对象。 -
如果查询结果为空,则返回
null。
数据访问层(Mapper)
java
@Select("select * from emp where password = #{password} and username = #{username}")
Emp testIdandPassword(Emp emp);
逻辑说明:
-
使用 MyBatis 的
@Select注解直接在接口方法上定义 SQL 查询。 -
参数
emp中的username和password被动态替换到 SQL 查询中。 -
查询结果映射到
Emp对象,如果匹配不到记录,返回null。
总结
本登录校验模块基于 Spring 和 MyBatis 实现了一个完整的用户登录流程。通过使用 JWT 令牌技术,不仅提升了系统的安全性,还提供了较高的扩展性。