springboot

依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<dependency>  
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

工具类

用来生成JWT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.manpower.util;  

import io.jsonwebtoken.*;

import java.util.Date;
import java.util.UUID;

public class JwtUtil {

//private static long time = 1000*10; // token 有效期为10秒
private static long time = 1000 * 60 * 60 * 24; // token 有效期为一天
private static String signature = "admin";

// 生成token ,三个参数是我实体类的字段,可根据自身需求来传,一般只需要用户id即可
public static String createJwtToken(String operNo, String operName, String organNo) {
JwtBuilder builder = Jwts.builder();
return builder
// header
.setHeaderParam("typ", "JWT")
.setHeaderParam("alg", "HS256")
// payload 载荷
.claim("username", "admin")
.claim("role", "admin")
.claim("date", new Date())
.setSubject("admin-test")
.setExpiration(new Date(System.currentTimeMillis() + time))
.setId(UUID.randomUUID().toString())
// signature 签名信息
.signWith(SignatureAlgorithm.HS256, signature)
// 用.拼接
.compact();
}

// 验证 token 是否还有效,返回具体内容
public static Claims checkToken(String token) {
if (token == null) {
return null;
}
JwtParser parser = Jwts.parser();
try {
Jws<Claims> claimsJws = parser.setSigningKey(signature).parseClaimsJws(token);
Claims claims = claimsJws.getBody();
System.out.println(claims.get("username"));
System.out.println(claims.get("role"));
System.out.println(claims.getId());
System.out.println(claims.getSubject()); // 签名
System.out.println(claims.getExpiration()); // 有效期
// 如果解析 token 正常,返回 claims return claims;
} catch (Exception e) {
// 如果解析 token 抛出异常,返回 null return null;
}
}
}

Config配置

只放行登录页面即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.manpower.config;  

import com.manpower.interceptor.MyInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

@Configuration
public class MyInterceptorConfig extends WebMvcConfigurationSupport {

@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/login");
}
}

Interceptor拦截器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package com.manpower.interceptor;  

import com.manpower.util.JwtUtil;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {
@Autowired
StringRedisTemplate redisTemplate;

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String requestToken = request.getHeader("Authorization");
if(!StringUtils.isEmpty(requestToken)){
Claims claims = JwtUtil.checkToken(request.getHeader("Authorization"));
if (claims != null) {
String token = redisTemplate.opsForValue().get("operToken"+claims.get("operNo"));
if(Boolean.TRUE.equals(redisTemplate.hasKey("operToken" + claims.get("operNo")))){
if(requestToken.equals(token)){
// token正确
return true;
}else {
// token错误,判为并发登录,挤下线
// 对应的修改响应头的状态,用于前端判断做出相应的策略
response.setStatus(411);
return false;
}
}else {
// token不存在于redis中,已过期
response.setStatus(410);
return false;
}
}
// 解析token中的用户信息claims为null
response.setStatus(409);
return false;
}
// requestToken为空
response.setStatus(409);
// System.out.println(method);
return true;
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// System.out.println("执行完方法之后,但是在视图渲染之前");
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// System.out.println("视图渲染之后,可以做一些清理工作");
}
}

Controller层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.manpower.controller;  

import com.manpower.entity.Staff;
import com.manpower.service.IStaffService;
import com.manpower.util.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

@CrossOrigin
@RestController
@RequestMapping("/login")
public class LoginController {
@Resource
private IStaffService staffService;

@PostMapping()
private Staff loginIn(@RequestBody Staff staff) {
Staff staff1 = staffService.getById(staff.getId());
// System.out.println(staff1);
if (staff1 == null || !staff1.getPassword().equals(staff.getPassword())) {
return null;
}
return staff1;
}

@GetMapping("/checkToken")
public Claims checkToken(HttpServletRequest request) {
String token = request.getHeader("token");
return JwtUtil.checkToken(token);
}
}