3、JWT深入理解及实战

JSON Web Token (JWT): 理解与应用 JSON Web Token (JWT) 阅读详情

JWT深入理解及实战

1、概念

JWT,全称JSON Web Token,官网地址https://jwt.io,是一款出色的分布式身份校验方案。可以生成token,也可 以解析检验token。

2、三要素

  • 头部:主要设置一些规范信息,签名部分的编码格式就在头部中声明。
  • 载荷:token中存放有效信息的部分,比如用户名,用户角色,过期时间等,但是不要放密码,会泄露!
  • 签名:将头部与载荷分别采用base64编码后,用“.”相连,再加入盐,最后使用头部声明的编码类型进行编码,就得到了签名。

3、安全性分析

从JWT生成的token组成上来看,要想避免token被伪造,主要就得看签名部分了,而签名部分又有三部分组成,其

中头部和载荷的base64编码,几乎是透明的,毫无安全性可言,那么最终守护token安全的重担就落在了加入的盐

上面了!

试想:如果生成token所用的盐与解析token时加入的盐是一样的。岂不是类似于中国人民银行把人民币防伪技术

公开了?大家可以用这个盐来解析token,就能用来伪造token。

这时,我们就需要对盐采用非对称加密的方式进行加密,以达到生成token与校验token方所用的盐不一致的安全

效果!

4、组成详解

一个 JWT 实际上就是一个字符串,它由三部分组成,头部、载荷与签名。

4.1、头部(Header)
头部用于描述关于该 JWT 的最基本的信息,例如其类型以及签名所用的算法等。这也 

可以被表示成一个 JSON 对象。 

{"typ":"JWT","alg":"HS256"} 

105106 

在 头 部 指 明 了 签 名 算 法 是 HS256 算 法 。 

我 们 进 行 BASE64 编 码 

( http://base64.xpcha.com/ ) , 编 码 后 的 字 符 串 如 下 : 

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 
4.2、载荷(playload)

载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包

含三个部分:

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

iss: jwt 签发者

sub: jwt 所面向的用户

aud: 接收 jwt 的一方

exp: jwt 的过期时间,这个过期时间必须要大于签发时间

nbf: 定义在什么时间之前,该 jwt 都是不可用的.

iat: jwt 的签发时间

jti: jwt 的唯一身份标识,主要用来作为一次性 token

2 .公共的声明

公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.

但不建议添加敏感信息,因为该部分在客户端可解密。

3. 私有的声明

私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为

base64 是对称解密的,意味着该部分信息可以归类为明文信息。

这个指的就是自定义的 claim。比如前面那个结构举例中的 admin 和 name 都属

于自定的 claim。这些 claim 跟 JWT 标准规定的 claim 区别在于:JWT 规定的 claim,

JWT 的接收方在拿到 JWT 之后,都知道怎么对这些标准的 claim 进行验证(还不

知道是否能够验证);而 private claims 不会验证,除非明确告诉接收方要对这些 claim

进行验证以及规则才行。定义一个 payload:

{“sub”:“1234567890”,“name”:“John Doe”,“admin”:true}

然后将其进行 base64 加密,得到 Jwt 的第二部分。

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRta

W4iOnRydWV9

4.3、签证(signature)

jwt 的第三部分是一个签证信息,这个签证信息由三部分组成:

header (base64 后的)

payload (base64 后的)

secret

这个部分需要 base64 加密后的 header 和 base64 加密后的 payload 使用.连接组成

的字符串,然后通过 header 中声明的加密方式进行加盐 secret 组合加密,然后就构成了

jwt 的第三部分。107

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFt

ZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjo

YZgeFONFh7HgQ

注意

secret 是保存在服务器端的,

jwt 的签发生成也是在服务器端的,secret 就是用来进行

jwt 的签发和 jwt 的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。

一旦客户端得知这个 secret, 那就意味着客户端是可以自我签发 jwt 了。

5、使用场景

1. 一次性验证

比如用户注册后需要发一封邮件让其激活账户,通常邮件中需要有一个链接,这个链接

需要具备以下的特性:能够标识用户,该链接具有时效性(通常只允许几小时之内激活),

不能被篡改以激活其它可能的账户……这种场景就和 jwt 的特性非常贴近,jwt 的

payload 中固定的参数:iss 签发者和 exp 过期时间正是为其做准备的。

2.restful api 的无状态认证

使用 jwt 来做 restful api 的身份认证也是值得推崇的一种使用方案。客户端和服务

端共享 secret;过期时间由服务端校验,客户端定时刷新;签名信息不可被修改…spring

security oauth jwt 提供了一套完整的 jwt 认证体系,以笔者的经验来看:使用 oauth2

或 jwt 来做 restful api 的认证都没有大问题,oauth2 功能更多,支持的场景更丰富,后

者实现简单。

3.使用 jwt 做单点登录+会话管理(不推荐)

6、 工具类

导包

"io.jsonwebtoken:jjwt-api:$jsonwebtoken_version"
"io.jsonwebtoken:jjwt-impl:$jsonwebtoken_version"
"io.jsonwebtoken:jjwt-jackson:$jsonwebtoken_version"

工具一共如下Payload、JwtUtils、JwtClaim三个:

Payload

import lombok.Data;
import java.util.Date;

/**
 * @author :
 * @date :Created in 19:30 2022/7/18
 * @description :
 * @version: 1.0
 */
@Data
public class Payload<T> {
    private String id;
    private T userInfo;
    private Date expiration;
}

JwtClaim

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author :
 * @date :Created in 19:27 2022/7/18
 * @description :Payload泛型 
 * @version: 1.0
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class JwtClaim {

    /**
     *登录账号名,唯一
     */
    private String username;


    /**
     * 业务入口
     */
    private Integer clientType;

}

JwtUtils

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.joda.time.DateTime;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;
import java.util.UUID;

/**
 * @author :
 * @date :Created in 16:30 2022/7/18
 * @description :
 * @version: 1.0
 */
public class JwtUtils {

    private static final String JWT_PAYLOAD_USER_KEY = "userinfo";

    public static final String BEARER_PREFIX = "Bearer ";

    public static final int EXPIRE_TIME = 24 * 60 * 3;

    /**
     * 私钥加密token
     *
     * @param jwtClaim   载荷中的数据
     * @param privateKey 私钥
     * @param expire     过期时间,单位分钟
     * @return JWT
     */
    public static String generateTokenExpireInMinutes(Object jwtClaim, PrivateKey privateKey, int expire) {
        return Jwts.builder()
                .claim(JWT_PAYLOAD_USER_KEY, GsonSerializeUtils.toString(jwtClaim))
                .setId(createJTI())
                .setExpiration(DateTime.now().plusMinutes(expire).toDate())
                .signWith(privateKey, SignatureAlgorithm.RS256)
                .compact();
    }

    /**
     * 私钥加密token
     *
     * @param userInfo   载荷中的数据
     * @param privateKey 私钥
     * @param expire     过期时间,单位秒
     * @return JWT
     */
    public static String generateTokenExpireInSeconds(Object userInfo, PrivateKey privateKey, int expire) {
        return Jwts.builder()
                .claim(JWT_PAYLOAD_USER_KEY, GsonSerializeUtils.toString(userInfo))
                .setId(createJTI())
                .setExpiration(DateTime.now().plusSeconds(expire).toDate())
                .signWith(privateKey, SignatureAlgorithm.RS256)
                .compact();
    }

    /**
     * 公钥解析token
     *
     * @param token     用户请求中的token
     * @param publicKey 公钥
     * @return Jws<Claims>
     */
    private static Jws<Claims> parserToken(String token, PublicKey publicKey) {
        return Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token);
    }

    private static String createJTI() {
        return new String(Base64.getEncoder().encode(UUID.randomUUID().toString().getBytes()));
    }

    /**
     * 获取token中的用户信息
     *
     * @param token     用户请求中的令牌
     * @param publicKey 公钥
     * @return 用户信息
     */
    public static <T> Payload<T> getInfoFromToken(String token, PublicKey publicKey, Class<T> userType) {
        Jws<Claims> claimsJws = parserToken(token, publicKey);
        Claims body = claimsJws.getBody();
        Payload<T> claims = new Payload<>();
        claims.setId(body.getId());
        claims.setUserInfo(GsonSerializeUtils.toBean(body.get(JWT_PAYLOAD_USER_KEY).toString(), userType));
        claims.setExpiration(body.getExpiration());
        return claims;
    }

    /**
     * 获取token中的载荷信息
     *
     * @param token     用户请求中的令牌
     * @param publicKey 公钥
     * @return 用户信息
     */
    public static <T> Payload<T> getInfoFromToken(String token, PublicKey publicKey) {
        Jws<Claims> claimsJws = parserToken(token, publicKey);
        Claims body = claimsJws.getBody();
        Payload<T> claims = new Payload<>();
        claims.setId(body.getId());
        claims.setExpiration(body.getExpiration());
        return claims;
    }
}
揭秘JWT认证:从代码到Postman实战,深入理解无状态认证的奥秘 JWT认证实战指南 本文深入解析JWT认证的核心机制,通过Express中间件代码展示认证流程,并详细指导Postman测试方法。主要内容包括: 核心中间件解析:逐行讲解authenticateToken中间件,从令牌提取、验证到用户信息附加的全过程 Postman测试指南: 环境变量设置 用户注册/登录流程 受保护资源访问的令牌使用 关键特性解析: 无状态认证原理 令牌有效期设置 请求头中Bearer令牌的正确传递方式 文章通过实战演示JWT的自包含特性,即使后端清空用户数据,已签发的令牌仍能有效认证的原 阅读详情

相关推荐

JWT(json web token)认证实现【Playload 存储自定义对象】

会将空转为字符串“null”生成jwt:sign(

专注于计算机研发知识和资讯分享 1799

JSON Web Tokens 官网和官方文档

官网:https://jwt.io/ 官方文档:https://jwt.io/introduction

你今天真好看呀 2632

JWT - 令牌认证(认证流程和原理、Jwt 工具类、搭配 Redis 使用)

1. 首先前端将用户名和密码发送给后端,后端对用户名和密码校验成功后,会将用户 id 和其他信息作为 payload ,然后将其分别进行 Base64 编码,拼接,最后再签名,形成一个 JWT(Token). 形成的 JWT 就形同 xxx.yyy.zzz 这种结构的字符串.http 协议是一种无状态的协议,也就意味着当用户第一次通过用户名和密码登录成功以后,下一次再请求的时候,用户还需要再进行登录才行,因为根据 http 协议,我们不能知道是哪个用户发出的请求.

CYK_byte的博客 2万+

JWT -- JSON WEB TOKEN

01、什么是JWT 官网:https://jwt.io/introduction Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。 一句话:JWT用

qq_32904533的博客 621

SpringBoot 中使用 JWT 案例分享详解

SpringBoot 中使用 JWT 案例分享详解

不迁怒,不贰过。小知识,大智慧。 6087

CMU的local_planner学习笔记

ros::Subscriber subOdometry = nh.subscribe//当接收到/state_estimation话题消息更新时启动odometryHandler回调函数 (消息格式:nav_msgs::Odometry消息内容:关于机器人或车辆的位置和方向(姿态)信息)pcl::PointCloud::Ptr freePaths(new pcl::PointCloud());

qq_35971623的博客 3885

springboot+vue宿舍管理系统

一、项目介绍 1.技术要点 html、css3、js、vue基础 2.适合人群 有html、css3、js、vue基础,想学习vue、element ui开发后台管理系统的在校大学生、工作人员; 想学习如何实现动态菜单、动态路由、按钮权限的在职人员; 3.学习收获 1.学会使用vue-admin-template搭建后台系统; 2.vue-admin-template登录源码、权限权限验证流程分析; 3.vue动态菜单、动态路由、按钮权限实现原理,代码实现; 4.通用弹框、tree组件优

lcy198910的博客 434

深入CRSF协议数据包:手撕STM32代码,教你像调试串口一样分析ELRS遥控数据流

本文深入解析CRSF协议数据包,通过手撕STM32代码,教你如何像调试串口一样分析ELRS遥控数据流。从硬件准备到数据包捕获状态机设计,再到高级数据分析技巧和实战应用,全面覆盖CRSF协议的解析与优化,帮助开发者构建稳定可靠的通信系统。

weixin_29194693的博客 338

从Java全栈开发到微服务架构:一场真实面试的深度复盘

等通知吧,我们会尽快安排下一步。这次面试展示了李明作为一名经验丰富的Java全栈开发者,在多个技术领域都有深入的理解和实践经验。他不仅掌握了Java语言和JVM优化,还在微服务架构、前后端分离、数据库设计、消息队列、缓存策略、安全认证、CI/CD、监控日志等多个方面展现了扎实的技术功底。无论是代码示例还是实际问题解答,都体现了他在真实项目中的实战经验。这种全面的技术能力和良好的沟通表达,使他成为了一名极具竞争力的候选人。

CatchLight的博客 913

SD--根据订单创建出库单(相关的函数列表的介绍系列篇(2))

创建订单样例代码参见:http://blog.youkuaiyun.com/CompassButton/archive/2007/05/09/1601712.aspx 可以根据一个订单或者部分订单项来创建出库单,代码如下:* Populating the item data lx_sales_item-ref_doc = l_vbeln. lx_sales_item-ref_item = c_000010

SAP BLOG--Jack Wu 6227

ubuntu打实时内核补丁教程以及安装后显卡驱动问题解决方法

在ubuntu20.04上安装成功,亲测有效 目录ubuntu打实时内核补丁教程1、下载实时内核2、解压和打补丁(patch)3、安装依赖和编译安装4、修改一些文件,便于之后切换内核5、重启电脑实时内核版本下安装nvidia显卡驱动的问题1、先切换回之前的内核(非实时)版本2、重装之前内核(非实时)版本下的显卡驱动3、切换回实时内核(按照上面的步骤)4、在实时内核下安装显卡驱动 ubuntu打实时内核补丁教程 安装目标系统:ubuntu20.04 电脑配置:i9,2080ti 1、下载实时内核 打开终端,输

weixin_39275295的博客 7996

什么是JWT?深入理解JWT从原理到应用

JWT(JSON Web Token)是一种用于在网络应用间传递和验证信息的开放标准(RFC 7519)。它通过使用数字签名或加密,将一些声明式的信息进行编码,生成一个经过验证的令牌。JWT主要由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。

万维网连五洲,二进制写尽天下事,喜欢结识新伙伴寻找志同道合的朋友,欢迎一起探讨学习 8015

Ubuntu docker镜像中下载安装 DPABI(DPARSF)

在Ubuntu服务器的docker镜像中用MATLAB运行DPABI(以及使用DPARSF的功能)。

Pandako's Blog 1723

深入理解JWT令牌:从原理到实战

本文全面介绍了JWT(JSON Web Token)的工作原理及应用。JWT是一种开放标准(RFC7519),由Header、Payload和Signature三部分组成,通过数字签名确保信息传输安全。其工作流程包括签发、传输和验证三个阶段,适用于身份认证、信息交换和单点登录等场景。JWT具有无状态、自包含、跨域支持等优势,但也需要注意密钥管理、令牌过期、敏感信息保护和存储方式等安全问题。文章强调正确理解JWT原理并采取适当防护措施的重要性,为现代应用开发提供了一种轻量级认证解决方案。

silver-kite的博客 1484

RK3568_Android15适配以太网网卡gmac+国产phy芯片YT8531

本文介绍了在Android15 SDK上适配正点原子ATK-DLRK3568开发板网卡的过程。开发板采用GMAC接口搭配YT8531C PHY芯片,包含两个千兆网口。主要内容包括:硬件原理图确认、网络链路连接方式、内核DTS配置(包括GMAC0和GMAC1的参数设置)、PHY驱动适配(基于motorcomm.c驱动文件)、PHY寄存器读写调试方法以及MAC地址设置方式。文章还分析了常见问题,如网卡注册后无法ping通网络的故障现象。通过详细的硬件确认和软件配置,实现了双网卡在Android系统上的完整适配。

Android/Linux驱动开发传帮带学习,让驱动入门门槛更低! 2021

从 Token 到 Agent:一文串起 AI 大模型核心概念

摘要:本文系统解析了现代AI系统的八大核心概念:Token(语言处理的最小单位)、Context(AI的短期记忆)、Prompt(指令接口)、Tool(能力扩展器)、MCP(工具生态协议)、Agent(自主智能体)和AgentSkill(专业技能封装)。文章揭示了这些概念如何共同构成AI从基础语言理解到自主决策的技术脉络,重点阐述了Token对计算成本的影响、Prompt工程的重要性、Tool如何突破AI的能力边界,以及Agent如何通过"感知-规划-执行-反思"循环完成复杂任务。最后指

jundao1997的专栏 251

深入理解JWT令牌:生成与验证

在现代Web应用中,安全高效地管理用户认证和信息传递显得尤为重要。传统的会话(Session)机制在某些情况下已无法满足分布式系统的需求,因此一种更简洁、自包含的方案应运而生——JSON Web Token(JWT)。JWT是一种基于JSON的访问令牌,能够安全地传递认证信息。本文将详细介绍JWT的生成和验证过程,并探讨在实际应用中如何确保令牌的安全性与有效性。

cooldream2009的博客 2478

信号处理算法:离散余弦变换(DCT)_(1).离散余弦变换(DCT)概述

离散余弦变换的数学定义如下:对于一个长度为NNN的离散信号xnx(n)xn,其DCT变换后的系数XkX(k)XkXk∑n0N−1xncos⁡πNn12kk012N−1Xkn0∑N−1​xncosNπ​n21​kk012N−1其中,kkk是频率指数,nnn是时间或空间索引。离散余弦变换(DCT)是一种强大的信号处理技术,广泛应用于图像压缩、音频处理、数据压缩等领域。

2401_87715305的博客 1558

深入理解 JWT

JWT(JSON Web Token)是一种无状态的分布式认证方案,解决了传统Session认证在扩展性、跨域和移动端支持上的痛点。JWT由Header、Payload、Signature三部分组成,采用Base64URL编码,通过签名机制确保安全性。其核心优势在于服务端无需存储状态,只需验证签名即可完成认证,特别适合微服务、单点登录等场景。但需注意Payload内容仅编码未加密,不应包含敏感信息。JWT通过算法和密钥保障防篡改能力,使分布式系统认证更加轻量和高效。

小飞的博客 374

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

JWT的深入理解

JWT的特点是自包含的,减少了服务器端的存储和查找开销,并提供了无状态的身份验证机制。JWT的优势在于它是自包含的,即令牌本身携带了用户信息和验证信息,减少了对服务器端存储和查找用户信息的开销。需要注意的是,为了保证安全性,JWT的签名部分应该使用安全的密钥进行签名,并且需要进行合适的过期时间设置和刷新机制来保护令牌的安全性。需要注意的是,为了保证JWT的安全性,应使用安全的密钥对JWT进行签名,并根据需求设置适当的过期时间和刷新机制,以保护令牌的安全性。它是对头部和载荷进行签名的结果,使用私钥进行签名。

qq_41973154的博客 586

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

【深入理解JWT】从认证授权到网关安全

当我们输入了用户名和密码,点击”登录“,网站服务器验证你的凭证....... 账户登录成功背后的流程是怎样的?

2301_79757798的博客 1766

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

深入理解 JWT:结构、原理与代码实战

JWT 是一个字符串这个字符串可以被放置在 HTTP头()中,也可以在 URL 参数或 POST 体里传递。它的最大优势是不需要服务端保存会话状态(无状态),因为所有必要的信息(如用户ID、角色、过期时间)都被编码到了令牌本身。本文是一篇关于的入门与实践指南。文章首先介绍了 JWT 作为一种轻量、自包含的开放标准(RFC 7519),用于在 Web 应用、移动应用或微服务架构中安全地传递用户身份与声明信息。其核心优势在于无状态,服务端无需保存会话。Header(头部):包含令牌类型(typ)和签名算法(

2402_83239589的博客 813

深入理解JWT令牌

目录1 JWT 介绍2 JWT适用场景3 JWT结构3.1 Header3.2 Payload3.3 Signature4 JWT实践5 JWT工作原理6 常见问题6.1 JWT 安全嗎?6.2 JWT Payload 內容可以被伪造嗎?6.3 如果我的 Cookie 被窃取了,那不就表示第三方可以做 CSRF 攻击?6.4 空间及长度问题?6.5 Token失效问题?7 JWT使用建议 1 JWT 介绍 JSON Web Token(JWT)是一个开放式标准(RFC 7519),它定义了一种紧凑(Com

赵广陆 680

SpringBoot笔记:SpringBoot集成JWT、Shiro实战

之前写过《Spring集成Shiro框架实战》,最近看了JWT,正好两个整合一下,加深一下理解。

u011047968的专栏 1238

【经典】深入理解令牌JWT之token

目录 1、什么是JWT 2、JWT能做什么 3、为什么是JWT 基于传统的Session认证 基于JWT的认证 4、JWT的结构是什么 5、使用JWT 总结 1、什么是JWT JWT官网地址:https://jwt.io/introduction/ 官方解释:JWT是Java Web Token的首字母简写,它定义了一个紧凑的,自包含的方式,用于在各方之间以Json对象安全的传输信息。此信息可以验证和信任,因为它是数字签名。jwt可以使用签名算法进行签名...

CodingLJ 1095

Refine 与 JWT:深入理解 JSON Web Token 认证机制及 Express 授权实战

JWT(JSON Web Token)是当前 Web 应用中最主流的无状态认证方案。本文以 Refine 仓库文档 [2024-03-11-jwt-authentication.md](https://link.gitcode.com/i/1834df9cfae58de4ee751774cb033db9) 为骨架,系统讲解 JWT 的标准结构、认证流程、与 Session 方案的对比,并完整复现其

gitblog_00640的博客 1009
上一篇: 2、加密算法介绍及RSA实战
下一篇: 4、JWT常见面试总结
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白de成长之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值