TA的每日心情 | 难过 2022-9-23 12:52 |
---|
签到天数: 201 天 [LV.7]常住居民III
|
JWT 全称 JSON Web Token 即 JSON Web 令牌
那么,什么是jwt:
JSON Web Token (JWT) 是一个开放标准 (RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地传输信息作为 JSON 对象。此信息可以验证和信任,因为它是数字签名的。 JWT 可以使用密钥(使用 HMAC 算法)或使用 RSA 或 ECDSA 的公钥/私钥对进行签名。

什么时候应该使用 JSON Web Tokens?
授权:这是使用 JWT 最常见的场景。用户登录后,每个后续请求都将包含 JWT,从而允许用户访问该令牌允许的路由、服务和资源。单点登录是当今广泛使用 JWT 的一项功能,因为它的开销很小并且能够在不同的域中轻松使用。
信息交换:JSON Web 令牌是在各方之间安全传输信息的好方法。因为可以对 JWT 进行签名(例如,使用公钥/私钥对),所以您可以确定发件人就是他们所说的那个人。此外,由于使用标头和有效负载计算签名,您还可以验证内容没有被篡改。

JSON Web Token 结构是什么?
JSON Web Tokens 由三部分组成,由点 (.) 分隔,它们是:标题、有效载荷(payload)、签名
因此,JWT 通常如下所示。
xxxxx.yyyyy.zzzzz
标头通常由两部分组成:令牌的类型,即 JWT,以及正在使用的签名算法,例如 HMAC SHA256 或 RSA。
令牌的第二部分是有效负载,其中包含声明。声明是关于实体(通常是用户)和附加数据的陈述。
签名用于验证消息在此过程中没有被更改,并且在使用私钥签名的令牌的情况下,它还可以验证 JWT 的发送者就是它所说的那个人。

为什么我们应该使用 JSON Web Tokens?
由于 JSON 不像 XML 那样冗长,因此在对其进行编码时,它的大小也更小,这使得 JWT 比 SAML 更紧凑。这使得 JWT 成为在 HTML 和 HTTP 环境中传递的不错选择。
安全方面,SWT 只能通过使用 HMAC 算法的共享密钥进行对称签名。但是,JWT 和 SAML 令牌可以使用 X.509 证书形式的公钥/私钥对进行签名。与签署 JSON 的简单性相比,使用 XML 数字签名签署 XML 而不引入隐蔽的安全漏洞是非常困难的。
JSON 解析器在大多数编程语言中都很常见,因为它们直接映射到对象。相反,XML 没有自然的文档到对象映射。这使得使用 JWT 比使用 SAML 断言更容易。
关于使用,JWT 用于 Internet 规模。这突出了 JSON Web 令牌在多个平台(尤其是移动平台)上客户端处理的便利性。


Go语言实现
由于其适用于http,拿go语言举例子再好不过了,下面的例子不涉及http层面,而涉及本地的构造和解析。
为了避开复杂的编码层面,我们将使用这个开源的jwt库:
https://github.com/golang-jwt/jwt
整个例子分为三个部分,首先,构造一个jwt,如图
第二个部分,负责解析
最后,在主函数生成并解析。
输出结果如图所示

完整示例代码如下
- package main
- import (
- "fmt"
- "github.com/golang-jwt/jwt"
- "time"
- )
- func main() {
- res := Create()
- Parse(res)
- }
- //构造函数
- func Create() string {
- //新建一个jwt,nbf标识时间,如果时间属于未来时间或不合法时间,将无法取出数据
- token := jwt.NewWithClaims(jwt.SigningMethodHS512, jwt.MapClaims{
- "nbf": time.Now().Unix(),
- "test": "消息",
- "test2": "消息2",
- })
- //对该jwt签名,这里的dinglz是秘钥
- tokenString, err := token.SignedString([]byte("dinglz"))
- //将最终的结果数据
- fmt.Println(tokenString, err)
- return tokenString
- }
- func Parse(tokenString string) {
- //解析
- token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
- if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
- return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
- //判断是不是已知加密方式
- }
- //返回秘钥
- return []byte("dinglz"), nil
- })
- //判断jwt是否可用
- if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
- //取出结果
- fmt.Println(claims["nbf"], claims["test"], claims["test2"]) //test、test2是在构建时写进的键
- } else {
- fmt.Println(err)
- }
- }
复制代码
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|