什么是JWT
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).定义了一种简洁的,自包含的方法用于通信双方之间以JSON对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名。
JWT官网: https://jwt.io
JWT的主要应用场景
身份认证在这种场景下,一旦用户完成了登陆,在接下来的每个请求中包含JWT,可以用来验证用户身份以及对路由,服务和资源的访问权限进行验证。由于它的开销非常小,可以轻松的在不同域名的系统中传递,所有目前在单点登录(SSO)中比较广泛的使用了该技术。 信息交换在通信的双方之间使用JWT对数据进行编码是一种非常安全的方式,由于它的信息是经过签名的,可以确保发送者发送的信息是没有经过伪造的。
JWT的结构
JWT包含了三部分:
Header 头部(标题包含了令牌的元数据,并且包含签名和/或加密算法的类型)
Payload 负载 (类似于飞机上承载的物品)
Signature 签名/签证
将这三段信息文本用.连接一起就构成了JWT字符串。
就像这样:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
下来我们通过springboot来实现jwt令牌的生成
添加pom依赖 待会需要用到json所以一起引入进来
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.51</version>
</dependency>
<dependency>
添加controller和service以及实体类,为了方便就没操作数据库我们采用固定的用户名和密码,整体的结果如下
controller
@RequestMapping("/user")
@RestController
public class UserController {
@Autowired
private UserService userService;
@PostMapping(value = "/login")
public String login(@RequestBody User user){
return userService.login(user);
}
}
实现类
public class UserServiceImpl implements UserService {
public static final String USERNAME = "admin";
public static final String PASSWORD = "admin";
@Override
public String login(User user) {
//忽略查询数据库
if (USERNAME.equals(user.getName()) && PASSWORD.equals(user.getPassword())){
//创建用户令牌信息
Map<String, Object> map = new HashMap<>();
map.put("role","USER");
map.put("success","SUCCESS");
map.put("username",user.getName());
//创建用户Token
String token = JwtUtil.createJWT(UUID.randomUUID().toString(), JSON.toJSONString(map), null);
//现在就可以存储tonken了,为了方便直接存到cookie里面去
Cookie cookie = new Cookie("Authoriztion", token);
cookie.setDomain("localhost");
cookie.setPath("/");
return token;
}
return "登录失败";
}
@Override
public List<User> getUserInfo() {
return null;
}
}
其中JwtUtil类为主要代码 代码如下,该类里面封装了生成token的信息
public class JwtUtil {
//令牌有效期 1小时
public static final Long JWT_TTL = 3600000L;
//jwt令牌信息
public static final String JWT_KEY = "mzjmc";
public static String createJWT(String id, String subject, Long ttlMillis){
//指定签名算法
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
//当前系统时间
long currentTimeMillis = System.currentTimeMillis();
//令牌签发的时间
Date date = new Date(currentTimeMillis);
//如果令牌的有效期为空则默认一小时
if (ttlMillis == null){
ttlMillis = JWT_TTL;
}
//令牌过期时间
long expMillis = currentTimeMillis + ttlMillis;
Date expDate = new Date(expMillis);
//生成秘钥
SecretKey secretKey = generalKey();
//封装jwt信息
JwtBuilder jwtBuilder = Jwts.builder();
jwtBuilder.setId(id); //唯一ID
jwtBuilder.setSubject(subject); //主题信息
jwtBuilder.setIssuer("admin"); //签发者
jwtBuilder.setIssuedAt(date); //签发时间
jwtBuilder.signWith(SignatureAlgorithm.HS256, secretKey); //算法及签名秘钥
jwtBuilder.setExpiration(expDate); //过期时间
return jwtBuilder.compact();
}
/**
* 生成秘钥
* @return
*/
public static SecretKey generalKey(){
byte[] encode = Base64.getEncoder().encode(JWT_KEY.getBytes());
return new SecretKeySpec(encode, 0, encode.length, "AES");
}
}
接下来我们可以测试通过登录获取token信息。指定了用户名和密码为admin
先来一组错的
再来一组对的
是不是很简单,2020-1024今天自己过节还是很Happy的