1. 一个JWT实际上就是一个字符串,由三部分组成 头部,载荷,签名
头部:事描述类型,签名,算法等 可以被表示成一个JSON对象
载荷:存放有效信息的地方 包含三个部分
(1)标准注册中的声明-建议但不强制使用
  iss:jwt签发者
  sub:jwt所面向的用户
  aud:接收jwt的一方
  exp:jwt的过期时间,时间必须大于签发时间
  nbf:定义在什么时间以前,这个jwt都是不可用的
  iat:jwt的签发时间
  jti:jwt的唯一身份标识,用来作为token
(2)公共的声明
  一般是公司相关的信息,由于这部分可以被解密,所以不要添加敏感信息
(3)私有的声明
  可以被解密,,
  可以自定义claim
  载荷的例子 {"sub":"1233","name":"John","admin":true}
签证:三部分
  header(base64后的)
  payload(base64后的)
  secret
2. 名词解释 Base64
  64个可打印二进制数据 2^6为64 每6个比特是一个单元,打印一个字符,3个字节有24个比特
  对应4个Base64 JDK中提供了BASE64Encoder BASE64Decoder 编码,解码
3. java的jjwt
  JJWT是一个提供端到端的JWT创建和验证的Java库
4. 使用

(一)引入依赖

  <dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.6.0</version>
  </dependency>

(二)测试使用

package BigTest.jwt;

import com.JwtBootApplication;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import java.text.SimpleDateFormat;
import java.util.Date;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = JwtBootApplication.class)
public class CreateJwtTest {
/*
* java.lang.IllegalArgumentException:
* secret key byte array cannot be null or empty.
* 是因为secret太简单了 没有加时间
* */
@Test
public void testJwt(){
JwtBuilder jwtBuilder = Jwts.builder().setId("888")
.setSubject("小白")
.setIssuedAt(new Date()) //setIssuedAt用于设置签发时间
.signWith(SignatureAlgorithm.HS256, "onetwothree"); //signWith用于设置签名秘钥
System.out.println(jwtBuilder.compact());
//eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1NzMyOTAwOTh9.-lqlLqmAG2qQ15Ge7IlcgIAgj0V54L0GCA5dJfM6Lw4 }
@Test
public void ParseJwtTest(){
String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1NzMyOTAwOTh9.-lqlLqmAG2qQ15Ge7IlcgIAgj0V54L0GCA5dJfM6Lw4";
Claims claims = Jwts.parser().setSigningKey("onetwothree").parseClaimsJws(token).getBody(); System.out.println("id="+claims.getId());
System.out.println("subject="+claims.getSubject());
System.out.println("IssueAt="+claims.getIssuedAt());
} /**
* 带过期时间的jwt-token
* ExpiredJwtException: token过期报错
*/
@Test
public void testJwt_time(){
long now = System.currentTimeMillis();
long exp = now + 1000*60;//设置时间为1分钟
JwtBuilder jwtBuilder = Jwts.builder().setId("888")
.setSubject("小白")
.setIssuedAt(new Date()) //setIssuedAt用于设置签发时间
.setExpiration(new Date(exp))//setExpiration设置token过期时间
.signWith(SignatureAlgorithm.HS256, "onetwothree"); //signWith用于设置签名秘钥
System.out.println(jwtBuilder.compact()); }
@Test
public void ParseJwtTest_time(){
String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODgiLCJzdWIiOiLlsI_nmb0iLCJpYXQiOjE1NzMyOTg0MDUsImV4cCI6MTU3MzI5ODQ2NX0.Rx-0BrJ2032aUz_vrttXw-9_idfQe3LHzCnLOWpsaqs";
Claims claims = Jwts.parser().setSigningKey("onetwothree").parseClaimsJws(token).getBody();
System.out.println("id="+claims.getId());
System.out.println("subject="+claims.getSubject());
System.out.println("IssueAt="+claims.getIssuedAt());
SimpleDateFormat sdf=new SimpleDateFormat("yyyy‐MM‐dd hh:mm:ss");
System.out.println("签发时间:"+sdf.format(claims.getIssuedAt()));
System.out.println("过期时间:"+sdf.format(claims.getExpiration()));
System.out.println("当前时间:"+sdf.format(new Date()) );
}
/*
* 自定义claims,上面的只存储了id和subject 自定义可以存储自己向存储的内容
* */
@Test
public void testJwt_claims(){
long now = System.currentTimeMillis();
long exp = now + 1000*60; //设置过期时间为1分钟
JwtBuilder claim = Jwts.builder().setId("9768")
.setSubject("zhangsan")
.setIssuedAt(new Date())
.signWith(SignatureAlgorithm.HS256,"onetwothree")
.setExpiration(new Date(exp))
.claim("roles", "admin")
.claim("address", "beijing");
System.out.println(claim.compact());
}
@Test
public void ParseJwtTest_claim(){
String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI5NzY4Iiwic3ViIjoiemhhbmdzYW4iLCJpYXQiOjE1NzMzMDg0ODUsImV4cCI6MTU3MzMwODU0NSwicm9sZXMiOiJhZG1pbiIsImFkZHJlc3MiOiJiZWlqaW5nIn0.Y-8hZIAlWzegSadQWSQGRc9gUBGlBznRT984jtqQZ-s";
Claims claims = Jwts.parser().setSigningKey("onetwothree").parseClaimsJws(token).getBody(); System.out.println("id:"+claims.getId());
System.out.println("subject:"+claims.getSubject());
System.out.println("roles:"+claims.get("roles"));
System.out.println("logo:"+claims.get("address"));
SimpleDateFormat sdf=new SimpleDateFormat("yyyy‐MM‐dd hh:mm:ss");
System.out.println("签发时间:"+sdf.format(claims.getIssuedAt()));
System.out.println("过期时间:"+sdf.format(claims.getExpiration()));
System.out.println("当前时间:"+sdf.format(new Date()) ); } }

(三)在springboot中的使用

在application.yml添加配置

jwt:
config:
key: zhedoumeishenme
ttl: 360000

 编写utils

package com.xxy.server.common.utils;

import io.jsonwebtoken.*;
import org.springframework.boot.context.properties.ConfigurationProperties; import java.util.Date; @ConfigurationProperties("jwt.config")//拿到 .yml中的参数
public class JwtUtils {
private String key;
private long ttl; //一个小时 public String getKey() {
return key;
} public void setKey(String key) {
this.key = key;
} public long getTtl() {
return ttl;
} public void setTtl(long ttl) {
this.ttl = ttl;
} /**
* 生成jwt
* @param id
* @param subject
* @param roles
* @return
*/
public String createJWT(String id, String subject, String roles){
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
JwtBuilder builder = Jwts.builder().setId(id)
.setSubject(subject)
.signWith(SignatureAlgorithm.HS256, key)
.setIssuedAt(now)
.claim("roles", roles);
if(ttl > 0){
builder.setExpiration(new Date(nowMillis+ttl));
} return builder.compact();
} /**
* 解析JWT
* @param jwtStr
* @return
*/
public Claims parseJWT(String jwtStr){
return Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(jwtStr)
.getBody();
}
}
Jwt请求拦截器
package com.xxy.server.common.interceptors;

import com.xxy.server.common.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* @Description: Jwt请求拦截器
* @Author: xuxiaoyu
* @Create: 2019-11-10 20:45
*/
@Component
public class JwtFilter extends HandlerInterceptorAdapter {
@Autowired
private JwtUtils jwtUtils; @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("经过了jwtfilter拦截器");
final String authHeader = request.getHeader("Authorization");
if (authHeader != null && authHeader.startsWith("Bearer ")) {
Claims claims = jwtUtils.parseJWT(authHeader);
if(claims != null){
if("admin".equals(claims.get("roles"))){
request.setAttribute("admin_claims", claims);
}
if("user".equals(claims.get("roles"))){
request.setAttribute("user_claims", claims);
}
}
}
return true;
}
}

配置到mvc中

package com.xxy.server.common.config;

import com.xxy.server.common.interceptors.JwtFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; /**
* description:该类可以来扩展Spirng MVC的功能
*/
@Configuration
public class MvcConfig extends WebMvcConfigurationSupport {
@Autowired
private JwtFilter jwtFilter;
/**
* description:添加默认视图映射,当访问localhost:8080/时,跳转到index.html页面
* params : registry
* @return void
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index"); }
/**
* description: Jwt请求拦截器,任何请求都会经过这个拦截器
* @param registry
*/
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtFilter)
.addPathPatterns("/**")
.excludePathPatterns("/login","/captcha");
}
}

然后在方法中就可以判断使用了

 Claims claims = (Claims) request.getAttribute("admin_claims");
if (claims == null) {
return HttpResultUtil.error("权限不足");
}

基于JWT的token认证机制的更多相关文章

  1. 基于JWT的Token认证机制及安全问题

    [干货分享]基于JWT的Token认证机制及安全问题 https://bbs.huaweicloud.com/blogs/06607ea7b53211e7b8317ca23e93a891

  2. iOS 开发之基于JWT的Token认证机制及解析

    在移动端和服务端通信中,一般有两种认证方式:token 和 session. 1.session/cookie 认证机制: 在服务端创建一个Session对象,同时在客户端的浏览器端创建一个Cooki ...

  3. token 与 基于JWT的Token认证

    支持跨域访问,无状态认证 token特点 支持跨域访问: Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通过HTTP头传输 无状态(也称:服务端可扩展行): ...

  4. 简单说说基于JWT的token认证方式

    一.什么是认证 好多人不知道什么是认证,认证,其实就是服务端确认用户身份.Http协议是无状态的,客户端发送一条请求,服务端返回一条响应,二者就算做成一单买卖,一拍两散.在很久以前,互联网所能提供的服 ...

  5. ASP.NET WebApi 基于JWT实现Token签名认证

    一.前言 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NET WebServi ...

  6. ASP.NET Web API 2系列(四):基于JWT的token身份认证方案

    1.引言 通过前边的系列教程,我们可以掌握WebAPI的初步运用,但是此时的API接口任何人都可以访问,这显然不是我们想要的,这时就需要控制对它的访问,也就是WebAPI的权限验证.验证方式非常多,本 ...

  7. 基于jwt的token验证

    一.什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519). 该token被设计为紧凑且安全的,特别适用于分布 ...

  8. 基于JWT的Token身份验证

    ​ 身份验证,是指通过一定的手段,完成对用户身份的确认.为了及时的识别发送请求的用户身份,我们调研了常见的几种认证方式,cookie.session和token. 1.Cookie ​ cookie是 ...

  9. 基于JWT的Token开发案例

    代码地址如下:http://www.demodashi.com/demo/12531.html 0.准备工作 0-1运行环境 jdk1.8 maven 一个能支持以上两者的代码编辑器,作者使用的是ID ...

随机推荐

  1. PHP开发-模板的使用

    通过今天晚上半个多小时的赵老师对模板的介绍,大致对模板的使用.结构以及开发模板的思想有了个大致的了解. 为什么要开发模板:模板就是将PHP发过过程中使用到.需要操作的事物封装成对象.以便在使用到的时候 ...

  2. 大数据之虚拟机配置和环境准备及hadoop集群搭建

    一.VMnet1和VMnet8路由器 VMware-workstation软件选择默认安装时,会自动创建VMnet1和VMnet8路由器设备.(安装失败使用CCleaner清理vm软件) VMnet1 ...

  3. caffe 官方demo python api

    Jupyter https://nbviewer.jupyter.org/github/BVLC/caffe/blob/master/examples/net_surgery.ipynb 涉及: - ...

  4. POJ - 1321 棋盘问题(简单搜索)

    题意:在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方 ...

  5. python 中的os.path.split()函数用法

    基本概念   os.path.split()通过一对链表的头和尾来划分路径名.链表的tail是是最后的路径名元素.head则是它前面的元素. 举个例子: path name = '/home/User ...

  6. 04 Unity2D

    Unity2D系统是Unity引擎进行2D制作时使用的 Sprite精灵:在Unity2D制作中将图片称作精灵(Sprite),为了提高游戏效率,降低对GPU的损耗,通常将一类的图片拼接成一张大图来使 ...

  7. C#高级编程(第9版) 第06章 数组

    好久没发东西了 , 一停下来就会变懒.... 虽然没完成,也就是它吧 --------------------------------- 以下正文 -------------------------- ...

  8. 学习spring的第二天

    对昨天的查漏:关于<bean>标签的scope属性,是由它决定原型和单例的,而不是说你java代码中用到了单例模式就是单例了. 其二就是lazy-init属性,它对于scope=" ...

  9. <kotlin>基础,杂七杂八(亲测有效)

    okhttp class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) ...

  10. cf1208 D Restore Permutation (二分+树状数组)

    题意 让你构造一个长度为n的序列,记为p1……pn,(这个序列是1~n的全排列的一种) 给你n个数,记为s1……sn,si的值为p1……pi-1中小于pi的数的和. 思路 显然,应该倒着来,也就是从p ...