首页 > 其他分享 >JWT笔记

JWT笔记

时间:2022-11-08 22:58:05浏览次数:384  
标签:return JWT 笔记 token Date import public

什么是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

相关文章

  • shell-文本处理学习笔记
    grep和egrep第一种形式:grep[option][pattern][file1file2...]第二种形式:command|grep[option][patern]选项:option-v不显示匹配行grep-vpythonfile......
  • Spring+SpringMVC学习笔记
    Spring学习笔记转载:https://www.yuque.com/kkuping/yuqzh2/vlgfylSpringMVC学习笔记转载:https://www.yuque.com/kkuping/yuqzh2/nxtocy......
  • c语言提高学习笔记——03-c提高10day_数据结构
    在学习c语言提高-数据结构总结了笔记,并分享出来。有问题请及时联系博主:​​Alliswell_WP​​,转载请注明出处。03-c提高10day_数据结构目录:一、队列(Queue)1、队列基本概念2......
  • Redis笔记
    概述Redis是一个内存数据库,也就是指存储到内存条上的数据,而MySQL是一个外存数据库,将数据库存储在硬盘(外存)中一、Linux安装下载完毕后,解压压缩包(自己找目录)tar-zxv......
  • 离散数学笔记-- 谓词
    基本概念:  看下面的小例子: 特性谓词,拓展定义域的时候: 看看就行: 具体展开:    具体应用3步骤:   一些逻辑变化:  仔细看下面的例......
  • UE4学习笔记16——【蓝图】冲刺;瞬移;多段跳
    P48.冲刺、瞬移、多段跳P48打开小白人的蓝图类,新建图表命名为“冲刺和瞬移”点一下组件中的“角色移动”,把细节中的“最大行走速度”改成93  添加节点“......
  • 【HDLBits刷题笔记】17 Verification: Wrting Testbenches&CS450
    Tb/clock这题要求给dut模块一个时钟。moduletop_module();regclk;always#5clk=~clk;initialbeginclk=0;enddutu0(clk);......
  • MFC学习笔记——07-MFC_19day
    在学习MFC总结了笔记,并分享出来。07-MFC_19day  一、基于对话框编程 (1)基于对话框编程对话框是一种特殊类型的窗口,绝大多数Windows程序都通过对话框与用户进行交互。在Vis......
  • 离散数学笔记
    特别注意:常元和变元  下面的栗子看看就行了:注意:永真和永假式:(重言和矛盾)栗子:    真值表的2个应用: 1判断永真 2判断式子是否等价:  ......
  • android 经典笔记总结
    pro android media developing graphics,music,videoand richmedia apps for smartphones and tablets第一章 android introduction  pla......