jwt超详细配置和教程

2023-11-17

一,什么是jwt

jsontoken,在各方之间以json对象安全的传送信息.此信息可以验证和信任因为它是数字签名的

从分布式认证流程中,我们不难发现,这中间起最关键作用的就是
token,token的安全与否,直接关系到系统的
健壮性,这里我们选择使用JWT来实现token的生成和校验。
JWT,全称JSON Web Token,官网地址https://jwt.io,是
一款出色的分布式身份校验方案。可以生成token,也可
以解析检验token。

二,jwt能做什么

1. 授权

这是使用JWT的最常见方案。一旦用户登录,每个后续请求将包括JWT,从而允许用户访问该令牌允许的路由,服务和资源。单点登录是当今广泛使用JWT的一项功能,因为它的开销很小并且可以在不同的域中轻松使用。

2.信息交换

JSON Web Token是在各方之间安全地传输信息的好方法。因为可以对JWT进行签名〈例如,使用公钥/私钥对),所以您可以确保发件人是他们所说的人。此外,由于签名是使用标头和有效负载计算的,因此您还可以验证内容是否遭到篡改。

三.为什么是jwt

基于传统的Session认证

  1. 认证方式
    传统使用session就是前端cookie保存一个sessionid,下次发送请求会自动携带

  2. 认证流程
    image-20230701170926508

  3. 暴露问题

    1. session保存在内存中,用户越多,内存负载越大
    2. 分布式应用的话限制了负载均衡能力
    3. cookie被截获容易收到跨站请求伪造攻击
    4. 在前后端分离系统中更加痛苦

    也就是说前后端分离在应用解耦后增加了部署的复杂性。通常用户一次请求就要转发多次。如果用session 每次携带sessionid到服务器,服务器还要查询用户信息。同时如果用户很多。这些信息存储在服务器内存中,给服务器增加负担。还有就是CSRF(跨站伪造请求攻击)攻击,session是基于cookie进行用户识别的,cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。还有就是
    sessionid就是一个特征值,表达的信息不够丰富。不容易扩展。而且如果你后端应用是多节点部署。那么就需要实现session共享机制。不方便集群应用。

    image-20230701182948515

认证流程

  • 首先,前端通过Web表单将自己的用户名和密码发送到后端的接口。这一过程一般是一个HTTP POST请求。建议的方式是通过SSL加密的传输(https协议),从而避免敏感信息被嗅探。

  • 后端核对用户名和密码成功后,将用户的id等其他信息作为JWT Payload(负载),将其与头部分别进行Base64编码拼接后签名形成一个JWT。形成的JWT就是一个形同lll.ZZZ.xxx的字符串。 token head.payload.singurater

  • 后端将JWT字符串作为登录成功的返回结果返回给前端。前端可以将返回的结果保存在localStorage或sessionStorage上,退出登录时前端删除保存的JWT即可。

  • 前端在每次请求时将JWT放入HTTP Header中的Authorization位。(解决XSS和XSRF问题)

  • 后端检查是否存在,如存在验证JWT的有效性。例如,检查签名是否正确;检查Token是否过期;检查Token的接收方是否是自己(可选)。

  • 验证通过后后端使用JWT中包含的用户信息进行其他逻辑操作,返回相应结果。

jwt优势

  • 简洁(Compact):可以通过URL,POST参数或者在HTTP header发送,因为数据量小,传输速度也很快-自包含( Self-contained)︰负载中包含了所有用户所需要的信息,避免了多次查询数据库
  • 因为Token是以JSON加密的形式保存在客户端的,所以JWT是跨语言的,原则上任何web形式都支持。
  • 不需要在服务端保存会话信息,特别适用于分布式微服务。

四,jwt结构是什么

令牌组成

token string --> header.payload.singnature

    1. 标头(header)
    2. 有效负载(payload)
    3. 签名(singnature)

header

  • 标头通常由两部分组成︰令牌的类型(即JWT)和所使用的签名算法,例如HNAC SHA256或RSA。它会使用Base64编码组成JWT结构的第一部分。
  • 注意:Base64是一种编码,也就是说,它是可以被翻译回原来的样子来的。它并不是一种加密过程。
{
    "alg" : "HS256",
    "typ" : "JWT"
}

payload

  • 令牌的第二部分,称为有效负载,其中包含声明.声明是有关实体(通常是用户)和其他数据的声明.同样的他会使用Base64编码组成JWT的第二部分
{
    "sub" : "123",
    "name" : "jhon"
    "admin" : "admin"
}

Signature

  • 前面两部分都是使用Base64 进行编码的,即前端可以解开知道里面的信息。Signature需要使用编码后的 header和 payload以及我们提供的一个密钥,然后使用header 中指定的签名算法(HS256)进行签名。签名的作用是保证JWT没有被篡改过
  • 如:
    HMACSHA256(base64UrlEncode( header) + “.” + base64Ur1Encode(payload) , secret);

image-20230701190859821

JWT 第三部分是签名。是这样生成的,首先需要指定一个 secret,该 secret 仅仅保存在服务器中,保证不能让其他用户知道。这个部分需要 base64URL 加密后的 header 和 base64URL 加密后的 payload 使用 . 连接组成的字符串,然后通过header 中声明的加密算法 进行加盐secret组合加密,然后就得出一个签名哈希,也就是Signature,且无法反向解密。

所以前两个部分基本上是明文,第三个部分是使用密钥和前面两部分进行加密后的验证信息

这部分的生成,是对前面两个部分的编码结果,按照头部指定的方式进行加密

比如:头部指定的加密方法是HS256,前面两部分的编码结果是eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJpYXQiOjE1ODc1NDgyMTV9

则第三部分就是用对称加密算法HS256对字符串eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJpYXQiOjE1ODc1NDgyMTV9进行加密,当然你得指定一个秘钥,比如shhhhh

HS256(`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJpYXQiOjE1ODc1NDgyMTV9`, "shhhhh")
// 得到:BCwUy3jnUQ_E6TqCayc7rCHkx-vxxdagUwPOWqwYCFc

令牌的验证

令牌在服务器组装完成后,会以任意的方式发送到客户端

客户端会把令牌保存起来,后续的请求会将令牌发送给服务器

而服务器需要验证令牌是否正确,如何验证呢?

首先,服务器要验证这个令牌是否被篡改过,验证方式非常简单,就是对header+payload用同样的秘钥和加密算法进行重新加密

然后把加密的结果和传入jwt的signature进行对比,如果完全相同,则表示前面两部分没有动过,就是自己颁发的,如果不同,肯定是被篡改过了。

传入的header.传入的payload.传入的signature
新的signature = header中的加密算法(传入的header.传入的payload, 秘钥)
验证:新的signature == 传入的signature

意思是我前面的两部分和密钥的加密结果和传入的第三部分进行比对
证为没有被篡改后,服务器可以进行其他验证:比如是否过期、听众是否满足要求等等,这些就视情况而定了

注意:这些验证都需要服务器手动完成,没有哪个服务器会给你进行自动验证,当然,你可以借助第三方库来完成这些操作

放在一起

  • 输出是三个由点分隔的Base64-URL字符串,可以在HTML和HTTP环境中轻松传递这些字符串,与基于XML的标准(例如SAMNL)相比,它更紧凑。
  • 简洁(Compact)
    可以通过URL,POST参数或者在 HTTP header发送,因为数据量小,传输速度快自包含(Self-contained)
    负载中包含了所有用户所需要的信息,避免了多次查询数据库

五,jwt使用

载荷(playload)

载荷就是存放有效信息的地方。这些有效信息包含三个部分:

(1)标准中注册的声明(建议但不强制使用)

Copyiss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击

(2)公共的声明

Copy公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息,但不建议添加敏感信息,因为该部分在客户端可解密。

例如:

Copy{"id":"123456","name":"MoonlightL","sex":"male"}

初步使用


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.9</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>jwt</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>jwt</name>
    <description>jwt</description>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--引入jwt-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

 @Test
    void contextLoads() {
        HashMap<String,Object> map = new HashMap<>();
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND,2000);
        System.out.println("时间"+calendar.getTime());

        String token = JWT.create().withHeader(map)//header
                .withClaim("userid", 21) //payload
                .withExpiresAt(calendar.getTime())//指定令牌过期时间
                .sign(Algorithm.HMAC256("111"));//签名
        System.out.println(token);

    }
@Test
    public void  test(){
    JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("111")).build(); //生成验证器
    DecodedJWT verify = jwtVerifier.verify("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2ODgyMTU1ODMsInVzZXJpZCI6MjF9.Q1tbjmbNVLzdJbWTGHKJjpHw5dXeyfsBrQp8TFC0yZs");
    Integer integer = verify.getClaim("userid").asInt();
    System.out.println(integer);
    
}

5.1 添加依赖

Copy<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.10.5</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.10.5</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.10.5</version>
    <scope>runtime</scope>
</dependency>

5.2 编码

Copyimport java.security.Key;
import java.util.Date;
import java.util.UUID;
import org.junit.Test;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;

public class JWTTest {

	@Test
	public void testJWT() {
		
		Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
		
		System.out.println("=============创建 JWT===========");
		Date now = new Date();
		JwtBuilder builder= Jwts.builder()
				                .setId(UUID.randomUUID().toString()) // 载荷-标准中注册的声明
				                .setSubject("admin") // 载荷-标准中注册的声明
				                .setIssuedAt(now) // 载荷-标准中注册的声明,表示签发时间
				                .claim("id", "123456") // 载荷-公共的声明
				                .claim("name", "MoonlightL") // 载荷-公共的声明
				                .claim("sex", "male") // 载荷-公共的声明
								.signWith(key); // 签证
		
		String jwt = builder.compact();
		System.out.println("生成的 jwt :" +jwt);
		
		System.out.println("=============解析 JWT===========");
		
		try {
			Jws<Claims> result = Jwts.parser().setSigningKey(key).parseClaimsJws(jwt);
			// 以下步骤随实际情况而定,只要上一行代码执行不抛异常就证明 jwt 是有效的、合法的
			Claims body = result.getBody();
			
			System.out.println("载荷-标准中注册的声明 id:" + body.getId());
			System.out.println("载荷-标准中注册的声明 subject:" + body.getSubject());
			System.out.println("载荷-标准中注册的声明 issueAt:" + body.getIssuedAt());
			
			
			System.out.println("载荷-公共的声明的 id:" + result.getBody().get("id"));
			System.out.println("载荷-公共的声明的 name:" + result.getBody().get("name"));
			System.out.println("载荷-公共的声明的 sex:" + result.getBody().get("sex"));
			
		} catch (JwtException ex) { // jwt 不合法或过期都会抛异常      
		    ex.printStackTrace();
		}
	}
}

执行结果:

Copy=============创建 JWT===========
生成的 jwt :eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI3ZjZmZjRlMC04YjM5LTQyYjUtOGRkNS0xN2M4ZjM5ZmZhNzMiLCJzdWIiOiJhZG1pbiIsImlhdCI6MTU0MzIwNTI4OSwiZXhwIjoxNTQzMjA1MzQ5LCJpZCI6IjEyMzQ1NiIsIm5hbWUiOiJNb29ubGlnaHRMIiwic2V4IjoibWFsZSJ9.BtEi-GCj5mCunXD_g0Cra7CSE_bMxhTzlOELWKc17I8
=============解析 JWT===========
载荷-标准中注册的声明 id:7f6ff4e0-8b39-42b5-8dd5-17c8f39ffa73
载荷-标准中注册的声明 subject:admin
载荷-标准中注册的声明 issueAt:Mon Nov 26 12:08:09 CST 2018
载荷-公共的声明的 id:123456
载荷-公共的声明的 name:MoonlightL
载荷-公共的声明的 sex:male

注意:加密和解密 JWT 必须是同一个 Key 对象

注意:解密 JWT 时,必须要抓取 JwtException 异常,只要抓取到该异常说明该 JWT 不可用了

六,jwt工具类

public class JWTUtils {
    public static final String SING="111";
    /**
     * @explain 生成token
     * @create 2023-07-01 20:28
     * @author linghanwu
     * @param
    * @return
    **/
    public  static String getToken(Map<String,String> map){
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.DATE,7);
        JWTCreator.Builder builder = JWT.create();
        map.forEach((k,v)->builder.withClaim(k,v));
        return builder.withExpiresAt(instance.getTime()) //设置过期时间
        .sign(Algorithm.HMAC256(SING));


    }
    /**
     * @explain 验证token合法性
     * @create 2023-07-01 21:18
     * @author linghanwu
     * @param
    * @return
    **/
    public static  DecodedJWT verify(String token){
        DecodedJWT verify = JWT.require(Algorithm.HMAC256(SING)).build().verify(token);
        return  verify;
    }
}

七,jwt整合springboot

创建过滤器

public class JWTInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
      //获取请求头中的令牌
        String token = request.getHeader("token");
        Map<String,Object> map = new HashMap<>();
        try {
            JWTUtils.verify(token); // 验证Token
            return true;
        } catch (TokenExpiredException e) {
            map.put("state", false);
            map.put("msg", "Token已经过期");
        } catch (SignatureVerificationException e){
            map.put("state", false);
            map.put("msg", "签名错误");
        } catch (AlgorithmMismatchException e){
            map.put("state", false);
            map.put("msg", "加密算法不匹配");
        } catch (Exception e) {
            e.printStackTrace();
            map.put("state", false);
            map.put("msg", "无效token");
        }
        String json = new ObjectMapper().writeValueAsString(map);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(json);
        return false;

    }
}

引入过滤器

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new JWTInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/users/**");
    }
}



八,jwt的缺点

  • 安全性没法保证,所以 jwt 里不能存储敏感数据。因为 jwt 的 payload 并没有加密,只是用 Base64 编码而已。
  • 无法中途废弃。因为一旦签发了一个 jwt,在到期之前始终都是有效的,如果用户信息发生更新了,只能等旧的 jwt 过期后重新签发新的 jwt。
  • 续签问题。当签发的 jwt 保存在客户端,客户端一直在操作页面,按道理应该一直为客户端续长有效时间,否则当 jwt有效期到了就会导致用户需要重新登录。那么怎么为 jwt 续签呢?最简单粗暴就是每次签发新的 jwt,但是由于过于暴力,会影响性能。如果要优雅一点,又要引入 Redis 解决,但是这又把无状态的 jw t硬生生变成了有状态的,违背了初衷。
    rceptor(new JWTInterceptor())
    .addPathPatterns(“/“)
    .excludePathPatterns(”/users/
    ”);
    }
    }



# 八,jwt的缺点

- 安全性没法保证,所以 jwt 里不能存储敏感数据。因为 jwt 的 payload 并没有加密,只是用 Base64 编码而已。
- 无法中途废弃。因为一旦签发了一个 jwt,在到期之前始终都是有效的,如果用户信息发生更新了,只能等旧的 jwt 过期后重新签发新的 jwt。
- 续签问题。当签发的 jwt 保存在客户端,客户端一直在操作页面,按道理应该一直为客户端续长有效时间,否则当 jwt有效期到了就会导致用户需要重新登录。那么怎么为 jwt 续签呢?最简单粗暴就是每次签发新的 jwt,但是由于过于暴力,会影响性能。如果要优雅一点,又要引入 Redis 解决,但是这又把无状态的 jw t硬生生变成了有状态的,违背了初衷。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

jwt超详细配置和教程 的相关文章

随机推荐

  • 【2019.11.12】C语言中求最大值和最小值的两种方法

    C语言中求最大值和最小值的两种方法 编写完整的程序 输入三个数 输出其中的最大数 最小数 输入说明 两个整数N1 N2 N3 输出说明 最大数 最小数 输入样例 5 4 9 输出样例 9 4 方法一 include
  • C++学习教程大纲

    以下是C 学习教程的大纲 第一部分 基础知识 C 简介 什么是C C 的历史 C 的特点和优势 开发环境的搭建 安装C 编译器 配置开发环境 第一个C 程序 Hello World程序 程序的结构 编译和运行程序 数据类型和变量 基本数据类
  • jQuery的三种$()

    号是jQuery 类 的一个别称 构造了一个jQuery对象 所以 可以叫做jQuery的构造函数 个人观点 呵呵 1 可以是 expresion 即css选择器 Xpath或html元素 也就是通过上述表达式来匹配目标元素 比如 a 构造
  • 应急响应篇:windows入侵排查

    前言 应急响应 Incident Response Service IRS 是当企业系统遭受病毒传播 网络攻击 黑客入侵等安全事件导致信息业务中断 系统宕机 网络瘫痪 数据丢失 企业声誉受损 并对组织和业务运行产生直接或间接的负面影响时 急
  • 《码上行动:零基础学会Python编程》书籍分享

    Python是一种高级的 面向对象的编程语言 由Guido van Rossum于1991年开发 它具有简洁 易读和可维护的语法 被广泛用于科学计算 Web开发 数据分析 人工智能等领域 以下是Python的一些特点和优势 简洁易读 Pyt
  • 还对Flutter理解不透?看完这些迟早成为大佬~

    Flutter是什么 Flutter简介 Flutter是谷歌的移动UI框架 可以快速在iOS和Android上构建高质量的原生用户界面 一份代码可以同时生成iOS和Android两个高性能 高保真的应用程序 Flutter目标是使开发人员
  • 2023年最火副业:Python爬虫兼职,一周赚7800元,一天只要两小时 !

    现在学习python的人越来越多了 跟大家简单如何利用python搞副业赚钱的 想要利用 Python 赚钱的方式还是比较多的 其中接单和投稿算是两种比较简单的方式了 如果你是业余学python爬虫 可以去淘宝上加了找了几个店铺直接问需要爬
  • 数据结构和算法(4):栈与队列

    栈 ADT 及实现 栈 stack 是存放数据对象的一种特殊容器 其中的数据元素按线性的逻辑次序排列 故也可定义首 末元素 尽管栈结构也支持对象的插入和删除操作 但其操作的范围仅限于栈的某一特定端 也就是说 若约定新的元素只能从某一端插入其
  • 文本域左边的文字处理

    文本域左边文字默认是bottom 如果想要左边文字与文本域顶部平齐 那么只需要设置label的vertical align的属性值为top即可 设置前 设置后
  • 代码分析(一)

    2021SC SDUSC 分析前言 对于APIJSON的代码分析首先就是 看一下该项目的作用以及如何进行 看一下原来不部署这个项目的正常流程 再来看一下部署上APIJSON后项目的流程走向 接下来开始按照这个流程对相应的代码进行分析 Abs
  • windows xcopy 复制文件夹命令 覆盖 或 跳过

    xcopy 拓展的复制命令 复制目录和下面的文件 保持目录结构 不能复制系统文件 隐藏文件 xcopy 源路径 目标路径 常用 复制并且覆盖 xcopy y srcPath dstPath 复制目录和目录下文件并且对目录下的子目录和子目录的
  • 一款好用的国产软件源代码缺陷分析平台 — CodeSense

    CodeSense是新一代的软件源代码缺陷深度分析平台 包含多个自研的代码分析引擎 同时提供开放的方案 支持多种商业 开源分析引擎集成并对结果进行集中展示 与目前市面的国外商业工具对比 在语言种类 功能 标准 缺陷分类数量上 已达到一致 额
  • 论文阅读-Training a Helpful and Harmless Assistant withReinforcement Learning from Human Feedback

    一 论文信息 论文名称 Training a Helpful and Harmless Assistant withReinforcement Learning from Human Feedback Github GitHub anthr
  • JavaWeb - 仿小米商场(4):首页商品分类展示

    JavaWeb 仿小米商场 4 首页线路分类展示 1 功能描述 接上篇JavaWeb 仿小米商场 3 登录与退出本篇博客将分析和实现旅游线路分类内容的查询和展示 此功能旨在控制 banner 顶部的展示内容 如以下H5页面所示 2 功能分析
  • Uniapp零基础开发学习笔记(9) -媒体组件音视频摄像头等的练习使用

    Uniapp零基础开发学习笔记 9 媒体组件音视频摄像头等的练习使用 基础组件部分 最后就只剩余媒体组件以及地图 和画布Canvas 以及浏览器组件web view 此次先看看媒体组件 重点学习前面几个 链接如下 https uniapp
  • 在Vue中当执行this.$emit() 时发生了什么?this.$emit() 的调用是异步的吗?

    当在Vue组件中调用this e m i t 时 实 际
  • 局域网设计

    一 局域网设计模型 1 局域网设计原则 考察物理链路 物理链路的带宽是网络设计的基础 分析数据流的特征 明确应用和数据流的分布特征 可以更加有效地进行资源分布 例如 企业邮件服务和工作组共享打印对于网络的需求是不一致的 采用层次化模型进行设
  • 【语义分割】【CVPR2022】BAM Note

    Topic 这是一篇CVPR 2022 Oral Paper 让我们继续体会小样本分割的魅力 Abstract 近年来 少镜头分割技术得到了广泛的发展 以往的工作大多试图通过分类任务的元学习框架来实现泛化 然而 训练的模型偏向于所见的类 而
  • Matlab相关性分析

    1 线性回归R方法 通过计算R方来看每个变量间的相关性 代码如下 X ones length X pre 1 X pre 注意 要计算具有常数项 截距 的模型的系数估计值 请在矩阵 X 中包含一个由 1 构成的列 b bint r rint
  • jwt超详细配置和教程

    一 什么是jwt jsontoken 在各方之间以json对象安全的传送信息 此信息可以验证和信任因为它是数字签名的 从分布式认证流程中 我们不难发现 这中间起最关键作用的就是 token token的安全与否 直接关系到系统的 健壮性 这