什么是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比对
    }
}

原文地址:http://www.cnblogs.com/Z-Dragon/p/16871539.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性