什么是JWT
- 全程为“Json Web Token”,其本质就是一个字符串,是将用户信息保存到一个Json字符串中,然后进行编码后得到token字符串,并且这个token带有签名信息,接收后可以校验是否被篡改,所以可以用于在各方之间安全地将信息作为Json对象传输。
构成
-
头部.载荷.签名
-
头部(Header)
JWT头是一个描述JWT元数据的JSON对象,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);typ属性表示令牌的类型,JWT令牌统一写为JWT。最后,使用Base64 URL算法将上述JSON对象转换为字符串保存。{ "alg": "HS256", "typ": "JWT" }
-
载荷(Payload)
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }
-
签名(Signature)
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), your-256-bit-secret )
1.所需依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
2.配置application.yml
dragon:
jwt:
secret: f4e2e52034348f86b67cde581c0f9eb5 #密钥
expire: 604800
3.编写工具类
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
@Component
@Slf4j
@Data
//获取配置文件的属性
@ConfigurationProperties(prefix = "dragon.jwt")
public class JwtUtils {
private String secret;
private long expire;
// private String header;
/**
* 生成jwt token
*/
public String generateToken(long userId) {
Date nowDate = new Date();
//过期时间
Date expireDate = new Date(nowDate.getTime() + expire * 1000);
return Jwts.builder()
.setHeaderParam("typ", "JWT")
.setSubject(userId+"")
.setIssuedAt(nowDate)
.setExpiration(expireDate)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
public Claims getClaimByToken(String token) {
try {
return Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
}catch (Exception e){
log.debug("validate is token error ", e);
return null;
}
}
/**
* token是否过期
* @return true:过期
*/
public boolean isTokenExpired(Date expiration) {
return expiration.before(new Date());
}
/**
* 校验token
*/
public boolean validateJwt(HttpServletRequest request){
String token = request.getHeader("token");
return token != null;
}
4.Controller
/**
* 登陆测试
* @param user
* @return
*/
@PostMapping("login")
public R login(@RequestBody User user, HttpServletResponse response,HttpServletRequest request){
if (user.getUserName()==null||user.getPassword()==null){
return R.error();
}
String newPassword = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getPassword,newPassword);
wrapper.eq(User::getUserName,user.getUserName());
User dbUser = userService.getOne(wrapper);
//生成token字符串
String token = jwtUtils.generateToken(dbUser.getId());
//存入redis
ValueOperations<String,String> ops = redisTemplate.opsForValue();
ops.set("tokenOld",token);
//响应请求头
response.setHeader("token",token);
// request.getSession().setAttribute("user",dbUser);
return token!=null?R.success(dbUser):R.error();
}
5.拦截器
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Autowired
private StringRedisTemplate redisTemplate;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println(new Date() + "--preHandle:" + request.getRequestURL());
ValueOperations<String,String> ops = redisTemplate.opsForValue(); // 表明取的是key,value型的数据
Object o = ops.get("tokenOld"); // 获取Redis数据库中key为tokenOld对应的value数据
String token = request.getHeader("token");
assert o != null;
return o.equals(token);//利用用户传入的token和缓存中的token比对
}
}
标签:return,JWT,笔记,token,Date,import,public
From: https://www.cnblogs.com/Z-Dragon/p/16871539.html