首页 > 编程语言 >JSON WEB TOKEN - 简单的token认证方式 - 告别session和cookie - Java Demo

JSON WEB TOKEN - 简单的token认证方式 - 告别session和cookie - Java Demo

时间:2023-08-14 10:46:29浏览次数:50  
标签:WEB Java Demo jwt JWT token claims import com

JWT简介

jwt非常适合前后分离 和 分布式的应用

不必在服务端存储session,本地也不用存储cookie

直接存两段信息即可

      localStorage["jwt"] = jwt; // token
      localStorage["name"] = json.name; // token中加密的某个字段,用于后期请求带上校验token是否被改

可以把认证相关的信息都存储在里面,添加拦截去进行校验即可

JWT认证流程:

  1. 用户登录成功,生成token,返回一个对象(包含token,用户名)
  2. 每次请求都带上这个对象(通过js存储在电脑)
  3. jwt过滤器会校验token解密之后的name是否和用户名相同,相同则放行
  4. 完成(后续可能需要加上token刷新的动作)

详细介绍:JWT 丨 JSON Web Tokens 丨 java-jwt | 详细介绍以及用法


完整的认证demo

点击查看 - 托管在github - 有说明
https://github.com/hisenyuan/SSM_BookSystem/tree/master/BookSystem_V3

maven依赖

<dependency>
      <groupId>com.auth0</groupId>
      <artifactId>java-jwt</artifactId>
      <version>3.2.0</version>
</dependency>

JWT生成与解密

package com.hisen.jars.jwt;

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.joda.time.DateTime;

/**
 * 利用java-jwt 3.2.0版本
 * 每个版本的方法不大一样
 * Created by hisenyuan on 2017/8/17 at 15:41.
 */
public class Jwt {
  private static final String SECRET = "XX#$%()(#*!()!KL<><MQLMNQNQJQK sdfkjsdrow32234545df>?N<:{LWPW_hisen";
  private static final String EXP = "exp";
  private static final String PAYLOAD = "payload";

    /**
   * 生成Token:jwt
   * @param object 传入的加密对象 - 放入PAYLOAD
   * @param maxAge 过期事件,单位毫秒
   * @param <T>
   * @return
   */
  public static <T> String sign(T object, long maxAge) {
    Map<String, Object> map = new HashMap<String, Object>();
    String jsonString = JSON.toJSONString(object);
    map.put("alg", "HS256");
    map.put("typ", "JWT");
    long exp = System.currentTimeMillis() + maxAge;
    System.out.println("JWTUtil 当前时间:"+new DateTime().toString("yyyy-MM-dd HH:mm:ss EE"));
    System.out.println("JWTUtil 过期时间:"+new DateTime(exp).toString("yyyy-MM-dd HH:mm:ss EE"));
    String token = null;
    try {
      token = JWT.create()
          .withHeader(map)//header
          .withClaim(PAYLOAD, jsonString)//存放的内容 json
          .withClaim(EXP, new DateTime(exp).toDate())//超时时间
          .sign(Algorithm.HMAC256(SECRET));//密钥
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return token;
  }

  /**
   * 解密token
   * @param token jwt类型的token
   * @param classT 加密时的类型
   * @param <T>
   * @return 返回解密后的对象 - 如果token过期返回空对象
   */
  public static <T> T unsign(String token, Class<T> classT)  {
    DecodedJWT decode = JWT.decode(token);
    Map<String, Claim> claims = decode.getClaims();
    if (claims.containsKey(EXP) && claims.containsKey(PAYLOAD)){
      long tokenTime = claims.get(EXP).asDate().getTime();
      long nowTime = new Date().getTime();
      // 判断令牌是否超时
      if (tokenTime > nowTime){
        String json = claims.get(PAYLOAD).asString();
        return JSON.parseObject(json, classT);
      }
    }
    return null;
  }
}

解密的另外一种写法

这种写法如果令牌超时,直接运行时异常,无法做相关处理

  /**
   * 解密token
   * @param token jwt类型的token
   * @param classT 加密时的类型
   * @param <T>
   * @return 返回解密后的对象 - 如果token过期返回空对象
   */
  public static <T> T unsign(String token, Class<T> classT)  {
    JWTVerifier verifier = null;
    try {
      verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
      DecodedJWT jwt = verifier.verify(token); // 如果超时,直接抛出运行时异常
      Map<String, Claim> claims = jwt.getClaims();
      if (claims.containsKey(EXP) && claims.containsKey(PAYLOAD)) {
        long tokenTime = claims.get(EXP).asDate().getTime();
        long now = new Date().getTime();
        // 判断令牌是否已经超时
        if (tokenTime > now) {
          String json = claims.get(PAYLOAD).asString();
          // 把json转回对象,返回
          return JSON.parseObject(json, classT);
        }
      }
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    } catch (TokenExpiredException e){
      e.printStackTrace();
    }
    return null;
  }

标签:WEB,Java,Demo,jwt,JWT,token,claims,import,com
From: https://www.cnblogs.com/zhangsai/p/17627978.html

相关文章

  • Java入门学习——day4(基础语法)
    一、关键字Java语言自己用到的一些词,有特殊作用的,我们称之为关键字,如:public、class、int、double......注意:关键字是Java用了的,我们就不能用来作为:类名、变量,否则会报错!注意:关键字很多,不用刻意去记,因为会报错。二、标识符标识符就是名字,我们写程序时会起一些名字,如类名......
  • 怎么解释web api 是无状态
    WebAPI被称为无状态,这主要是指它不会保存客户端的任何数据。每一个请求需要携带所有必要的信息,因为WebAPI不会记住前一次请求的信息。它的设计是完全无状态的,每一次请求都是一个全新的交互,不依赖于任何历史上的信息或状态。对应的,这种无状态的规范让WebAPI更易扩展和管理,同时也......
  • Webpack 使用详解
    Webpack是一个现代JavaScript应用程序的静态模块打包器。本文将详细介绍如何使用Webpack,以及提供代码示例。为了保持篇幅,我们将简要介绍Webpack的核心概念和功能。一、核心概念入口(entry):应用程序的起点。输出(output):打包后资源的输出位置。加载器(loader):将非JavaScript文......
  • java 用CompletableFuture来实现多线程查询和结果合并
    多线程查询结果合并使用CompletableFuture来实现多线程查询和结果合并。CompletableFuture提供了一种方便的方式来协调异步任务并处理其结果。下面是一个使用CompletableFuture的示例:importjava.util.ArrayList;importjava.util.List;importjava.util.concurrent.CompletableF......
  • 【web_逆向06】base64
    简介base64其实很容易理解.通常被加密后的内容是字节.而我们的密文是用来传输的(不传输谁加密啊).但是,在http协议里想要传输字节是很麻烦的一个事儿.相对应的.如果传递的是字符串就好控制的多.此时base64就应运而生了.26个大写字母+26个小写字母+10个数字+2个特殊符号(......
  • Java知识补漏
    Java知识补漏内存溢出在强制类型转换时,有可能产生内存溢出现象,如以下代码publicclassText01{publicstaticvoidmain(String[]args){inti=128;bytej=(byte)i;System.out.println(j);}}变量数字类型变量可以用下划线分割,不......
  • 【==是判断相等吗?---错辣】C++和JAVA中判断字符串值相等的区别
    参考文章:这里;这里;这里先上结论C++中的string类型可以使用==和!=来判断两个字符串的值是否相等;而JAVA不行,JAVA中==和!=是用来判断两个字符串的地址是否相同(或者说是对象是否相同,即是否为同一个对象)。C++中string#include<iostream>#include<string>usingnamespacestd;intmai......
  • java基础02
    数据类型扩展进制,二进制以0b开头,八进制以0开头,十六进制以0x(x必须为小写)开头,如:publicclasshello{publicstaticvoidmain(String[]args){inti=0b10;//二进制inti2=10;//十进制inti3=010;//八进制inti4=0x10;//十......
  • 【web_逆向05】URLEncode
    我们这网站中总能看到这样一种url,例如:百度中直接搜索"周杰伦"https://www.baidu.com/sugrec?&prod=pc_his&from=pc_web&json=1&sid=26350&hisdata=%5B%7B%22time%22%3A1691934763%2C%22kw%22%3A%22%E5%91%A8%E6%9D%B0%E4%BC%A6%22%2C%22fq%22%3A4%7D%5D&_t=1691934......
  • Java入门学习——day3(基础语法)
    使用变量的几个注意事项变量要先声明才能使用。这里的age没有声明,会标红,鼠标放在标红的age上出现了Cannotresolvesymbol'age',运行会报错!改正:变量是什么类型,就应该用来装什么类型的数据,否则报错。本来age是int类型,但是我们给了一个double类型。改正:变量是从定义开始到“}”......