java实现基于JWT的token登陆认证
前言
之前基于session的登录方式,是在用户登录成功后将用户信息存入到session中,这样不利于程序的横向扩展, 如果将项目部署多份,会出现session漂移的问题,并且随着登录用户的增加,会不断的占用服务端的内存资源;而现在这种基于token的登录方式,是在登录成功 后 将用户信息存入到客户端中,不会额外占用服务端的内存资源,并且通过签名和验签可以保证数据不被篡改,
又因为登录成功后是将用户的信息存入到客户端中,所以在进行横向扩展,部署多份的时候,不会产生session漂移的问题。
在项目中的使用
导入所需依赖
<!--引入JWT依赖,由于是基于Java,所以需要的是java-jwt-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
项目后台代码
登录认证相关代码
写一个简单的登陆测试一下怎么使用token
bean
public class User {
private Long userId;
private String userName;
private String password;
}
核心方法
package com.fh.jwt;
import com.fh.util.response.ResponseServer;
import com.fh.util.response.ServerEnum;
import io.jsonwebtoken.*;
import sun.misc.BASE64Encoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class JwtTokenUtils {
public static String createToken(Map<String,Object> map){
//jwt如何生成字符串
//声明头部信息
Map<String,Object> headerMap=new HashMap<String,Object>();
headerMap.put("alg","HS256");
headerMap.put("typ","JWT");
//设置负载:不要放着涉密的东西比如:银行账号密码,余额,身份证号
Map<String,Object> payload=new HashMap<String,Object>();
payload.putAll(map);
Long iat=System.currentTimeMillis();
//设置jwt的失效时间 一分钟
Long endTime = iat+60000l;
//签名值就是我们的安全密钥
String token=Jwts.builder()
.setHeader(headerMap)
.setClaims(payload)
.setExpiration(new Date(endTime))
.signWith(SignatureAlgorithm.HS256,getSecretKey("secretKey"))
.compact();
return token;
}
public static ResponseServer resolverToken(String token ){
Claims claims=null;
try {
claims = Jwts.parser()
.setSigningKey(getSecretKey("secretKey"))
.parseClaimsJws(token)
.getBody();
}catch (ExpiredJwtException exp){
System.out.println("token超时,token失效了");
return ResponseServer.error(ServerEnum.TOKEN_TIMEOUT);
}catch (SignatureException sing){
System.out.println("token解析失败");
return ResponseServer.error(ServerEnum.SAFETY_ERROR);
}
return ResponseServer.success(claims);
}
private static String getSecretKey(String key){
return new BASE64Encoder().encode(key.getBytes());
}
}
登录认证相关代码
控制层
package com.fh.controller;
import com.fh.jwt.JwtTokenUtils;
import com.fh.model.User;
import com.fh.service.UserService;
import com.fh.tokenauth.TokenCheckAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@CrossOrigin
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
public UserService service;
@RequestMapping("login")
public Map<String,Object> login(String userName,String password){
HashMap<String, Object> map = new HashMap<>();
User u = service.queryUser(userName);
if (u == null) {
map.put("code",3000);
return map;
}
// 生成token
Map<String,Object> m = new