Tlias 项目登录功能
登录校验
- ;要对所有接口做校验
/emps/.. /depts/..每个方法内实现太冗余, 因此一般使用 统一拦截.

会话技术

- 访问web 资源, 会话建立, 一方断开连接, 会话结束, 一次会话可以有多个请求
- 可以理解为 一个会话就是一个浏览器, 关闭浏览器会关闭会话.
- 会话跟踪: 识别请求是否来自同一个会话. 同一个会话可以共享数据.
- cookie
- session
- 令牌技术
cookie

- 存储在客户端(浏览器);
- 跨域: 前端一个服务器, 后端一个服务器, 跨域cookie不能传递.
session

- 存储在服务端

令牌

-
缺点: 自己实现
-
令牌伪造? 有签名防止伪造
jwt
- json web token

@Test
public void testGenJwt(){
Map<String, Object> claims = new HashMap<>();
claims.put("id",1);
claims.put("name","Tom");
String jwt = Jwts.builder()
.signWith(Jwts.SIG.HS256.key().build())
.claims(claims)
.expiration(new Date(System.currentTimeMillis() + 3600 * 1000))
.compact();
log.info(jwt);
}
// 生成
@Test
public void testGenJwt(){
Map<String, Object> claims = new HashMap<>();
claims.put("id",1);
claims.put("name","Tom");
// hs256 秘钥 32 字节或更长
String secretString = "itheimaaitheimaaitheimaaitheimaa";
SecretKey key = Keys.hmacShaKeyFor(secretString.getBytes());
SecretKey key1 = Jwts.SIG.HS256.key().random(new SecureRandom(secretString.getBytes())).build();
String jwt = Jwts.builder()
.signWith(key1) //.signWith(key, Jwts.SIG.HS256)
.claims(claims)
.expiration(new Date(System.currentTimeMillis() + 3600 * 1000))
.compact();
log.info(jwt);
}
// 验证
@Test
public void testJwtParse(){
String s = "eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiVG9tIiwiaWQiOjEsImV4cCI6MTczNTI5ODIwN30.wSQfN3enbWTxkoPxzC93DMdspWgePCN8ZDyoaLIwzm0";
String s1 = "eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiVG9tIiwiaWQiOjEsImV4cCI6MTczNTMwMzUyN30.EAtq-NKUXQ4ePmEthOCRyKImWYH1tISUOPRW8mI13Y8";
String secretString = "itheimaaitheimaaitheimaaitheimaa";
SecretKey key = Keys.hmacShaKeyFor(secretString.getBytes());
SecretKey key1 = Jwts.SIG.HS256.key().random(new SecureRandom(secretString.getBytes())).build();
Jws<Claims> claimsJws = Jwts.parser()
.verifyWith(key1) //.verifyWith(key, Jwts.SIG.HS256)
.build()
.parseSignedClaims(s1);
Map<String, Object> b = claimsJws.getPayload();
log.info(b.toString());
}
// https://jwt.io/

java
@PostMapping("/login")
public Result login(@RequestBody Emp emp){
log.info("员工登录{},{}",emp);
Emp empRet = empService.login(emp);
if(empRet == null){
return Result.error("用户名或密码错误");
}else{
Map<String ,Object> map = new HashMap<>();
map.put("id",empRet.getId());
map.put("name",empRet.getName());
map.put("username",empRet.getUsername());
String token = JwtUtils.getToken(map);// jwt 中包含员工登录的信息
return Result.success(token);
}
}
Filter



- 默认按类名排序
实现 @WebFilter

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("拦截器");
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 1. 获取请求url
String url = request.getRequestURI();
// 2. 有login 说明是登录请求, 放行
if(url.contains("login")){
filterChain.doFilter(servletRequest, servletResponse);
return;
}
// 3. 没有login , 查看token, 没有token 返回错误
String token = request.getHeader("token");
if(token == null||token.isEmpty()){
// Result.error("NOT_LOGIN");
// fastJson 转换
String notLogin = JSONObject.toJSONString(Result.error("NOT_LOGIN"));
response.getWriter().write(notLogin);
return;
}
// 4. 解析token, 错误 返回错误
try {
Claims claims = JwtUtils.parseToken(token);
} catch (Exception e) {
e.printStackTrace();
System.out.println("解析令牌失败");
String notLogin = JSONObject.toJSONString(Result.error("NOT_LOGIN"));
response.getWriter().write(notLogin);
return;
}
// 5. 放行
System.out.println("令牌合法, 放行");
filterChain.doFilter(servletRequest, servletResponse);
}
interceptor

路径

执行流程

实现 @Configuration
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle .........");
// 1. 获取请求url
String url = request.getRequestURI();
// 2. 有login 说明是登录请求, 放行
if(url.contains("login")){
return true;
}
// 3. 没有login , 查看token, 没有token 返回错误
String token = request.getHeader("token");
if(token == null||token.isEmpty()){
// Result.error("NOT_LOGIN");
// fastJson 转换
String notLogin = JSONObject.toJSONString(Result.error("NOT_LOGIN"));
response.getWriter().write(notLogin);
return false;
}
// 4. 解析token, 错误 返回错误
try {
Claims claims = JwtUtils.parseToken(token);
} catch (Exception e) {
e.printStackTrace();
System.out.println("解析令牌失败");
String notLogin = JSONObject.toJSONString(Result.error("NOT_LOGIN"));
response.getWriter().write(notLogin);
return false;
}
// 5. 放行
System.out.println("令牌合法, 放行");
return true;
}
区别
