一、pom文件引入jwt依赖
<!--JWT 令牌token -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
二、用户表vo类
@Data
public class Member {
private Long id;
private String username;
private String headImg;
private String account;
private String password;
private String token;
}
三、编写jwt工具类
@Slf4j
@Component
public class JwtTokenUtil implements Serializable {
private static final String CLAIM_KEY_USERNAME = "sub";
private static final long EXPIRATION_TIME = 2592000000L;
private static final String SECRET = "secret";
public String generateToken(Member member) {
Map<String, Object> claims = new HashMap<>(16);
claims.put(CLAIM_KEY_USERNAME, member.getAccount());
return Jwts.builder()
.setClaims(claims)
.setExpiration(new Date(Instant.now().toEpochMilli() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS512, SECRET)
.compact();
}
public Boolean validateToken(String token, Member member) {
String account = getAccountFromToken(token);
return (account.equals(member.getAccount()) && !isTokenExpired(token));
}
public Boolean isTokenExpired(String token) {
Date expiration = getExpirationDateFromToken(token);
if (expiration == null) {
return false;
}
return expiration.before(new Date());
}
public String getAccountFromToken(String token) {
try {
return Objects.requireNonNull(getClaimsFromToken(token)).getSubject();
} catch (Exception e) {
e.printStackTrace();
log.error("JWT出错了" + e.getMessage());
return "";
}
}
public Date getExpirationDateFromToken(String token) {
try {
return Objects.requireNonNull(getClaimsFromToken(token)).getExpiration();
} catch (Exception e) {
e.printStackTrace();
log.error("JWT出错了" + e.getMessage());
return null;
}
}
private Claims getClaimsFromToken(String token) {
try {
return Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
} catch (Exception e) {
e.printStackTrace();
log.error("JWT出错了" + e.getMessage());
return null;
}
}
}
四、编写jwt过滤器,用于token验证
@Component
public class jwtTokenFilter extends OncePerRequestFilter {
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Autowired
private MemberDao memberDao;
public static final String HEADER_STRING = "authorization";
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException{
String token = request.getHeader(HEADER_STRING);
if(filterPath(request.getServletPath())){
chain.doFilter(request,response);
return;
}
if(!StringUtils.isEmpty(token)){
String account = jwtTokenUtil.getAccountFromToken(token);
List<Member> list = memberDao.selectMemberByAccount(account);
if(list!=null && list.size()>0){
Member member = list.get(0);
if(jwtTokenUtil.validateToken(token,member)){
request.setAttribute("account",account);
request.setAttribute("member",JSONObject.toJSONString(member));
chain.doFilter(request,response);
return;
}
}
}
errorWrite(request,response);
}
private void errorWrite(HttpServletRequest request, HttpServletResponse response) throws IOException{
JsonBean<String> jsonBean = new JsonBean<>(false,"签名错误,请重新登录",0l,null,null,true);
response.setContentType("application/json; charset=utf-8");
response.setCharacterEncoding("UTF-8");
String userJson = convertObjectToJson(jsonBean);
OutputStream out = response.getOutputStream();
out.write(userJson.getBytes("UTF-8"));
out.flush();
}
private static String convertObjectToJson(Object object) throws JsonProcessingException {
if (object == null) {
return null;
}
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(object);
}
protected boolean filterPath(String path){
if(path.contains("/feign")){
return false;
}
return true;
}
}
五、mysql 数据表member
CREATE TABLE `member` (
`ID` bigint(10) NOT NULL AUTO_INCREMENT,
`ACCOUNT` varchar(50) DEFAULT NULL COMMENT '账号',
`HEAD_IMG` varchar(255) DEFAULT NULL,
`USERNAME` varchar(50) DEFAULT NULL,
`PASSWORD` varchar(100) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
INSERT INTO `sql_test`.`member`(`ID`, `ACCOUNT`, `HEAD_IMG`, `USERNAME`, `PASSWORD`) VALUES (1, 'cmw123', 'logo', 'cmw', '114466a7c5300d5e33caeb4e1bdbae54');
六、登录签名,获取令牌token
@Slf4j
@RestController
@RequestMapping("/jwt")
public class jwtLoginController {
@Autowired
private MemberDao memberDao;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@RequestMapping("/login")
public JsonBean<Member> login(String account, String password){
try {
if (StringUtils.isEmpty(account) || StringUtils.isEmpty(password)) {
return new JsonBean<>(false, "账号或密码输入错误", 0l, null);
}
List<Member> list = memberDao.selectMemberByAccount(account);
if (list != null && list.size() > 0) {
Member member = list.get(0);
String newPwd = new Md5Hash(password, account, 2).toString();
int count = memberDao.checkMemberAccount(member.getAccount(), newPwd);
if (count > 0) {
log.info("登录成功");
String token = jwtTokenUtil.generateToken(member);
member.setToken(token);
return new JsonBean<>(true, "登录成功", 1l, member);
} else {
return new JsonBean<>(false, "密码错误,请重试", 0l, null);
}
} else {
return new JsonBean<>(false, "账号错误,请重试", 0l, null);
}
}catch (Exception e){
return new JsonBean<>(false,"登录失败,请重试",0l,null);
}
}
}
七、测试
登录,获取token: http://127.0.0.1:1234/jwt/login?account=cmw123&password=123456
访问:http://127.0.0.1:1234/feign/basic?id=8229
Headers中authorization令牌
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/cf26f88e9b87b6ab313220727d8b690d.png)
去除Headers中authorization令牌
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/b33d1e00257d290c337a1aedd371db4b.png)