正文

golang原生实现JWT的示例代码(golang开发是什么)墙裂推荐

image-20230429184039413.png

文章摘要

这篇文章介绍了在Go语言中自定义实现JSON Web Token(JWT)的验证与解析过程。文章详细讲解了如何封装JWT的结构体、生成签名的方法、解析token的流程,并提供了一个中间件示例用于验证token。文章还包含了一个简单的测试用例,展示了如何在应用中使用JWT中间件获取和验证token。此外,文章指出了在实际应用中可能会扩展的功能,如密钥管理、时间限制等。文章内容简洁明了,适合需要了解JWT实现细节的开发者参考。 总结来说,文章的核心内容是展示了如何在Go语言中实现JWT的自定义验证与解析,涵盖了从签名生成到token验证的完整流程。


目录获取Token解析Token实际使用测试结果结语

JWT(JSON Web Token)是一种基于JSON的安全令牌,可以用于在不同系统之间传输认证信息。在Go中实现JWT验证,可以通过标准库、和来编写自己的JWT。

我们在此封装一个JWT的struct结构体(由于除了Payload,其他很大可能不会在其他地方用到,所以不公开)

type JWT struct { header string Payload string signature string }

将base64的编码封装一下方便使用

func encodeBase64(data string) string { return base64.RawURLEncoding.EncodeToString([]byte(data)) }

我们封装一个用来生成签名的方法

func generateSignature(key []byte, data []byte) (string, error) { // 创建一个哈希对象 hash :=hmac.New(sha256.New, key) // 将要签名的信息写入哈希对象中 hash.Write(data) _, err :=hash.Write(data) if err !=nil { return “”, err } // hash.Sum()计算签名,在这里会返回签名内容 // 将签名经过base64编码生成字符串形式返回。 return encodeBase64(string(hash.Sum(nil))), nil }

我们封装一个CreateToken用于生成Token(该方法的参数key为(生成签名所使用的密钥))

func CreateToken(key []byte, payloadData any) (string, error) { // 标准头部 header :=`

我们封装一个解析token的方法

func ParseJwt(token string, key []byte) (*JWT, error) { // 分解规定,我们使用.进行分隔,所以我们通过.进行分隔成三个字符串的数组 jwtParts :=strings.Split(token, “.”) // 数据数组长度不是3就说明token在格式上就不合法 if len(jwtParts) !=3 { return nil, fmt.Errorf(“非法token”) } // 分别拿出 encodedHeader :=jwtParts[0] encodedPayload :=jwtParts[1] signature :=jwtParts[2] // 使用key将token中的头部和负载用.连接后进行签名 // 这个签名应该个token中第三部分的签名一致 confirmSignature, err :=generateSignature(key, []byte(encodedHeader+”.”+encodedPayload)) if err !=nil { return nil, fmt.Errorf(“生成签名错误”) } // 如果不一致 if signature !=confirmSignature { return nil, fmt.Errorf(“token验证失败”) } // 将payload解base64编码 dstPayload, _ :=base64.RawURLEncoding.DecodeString(encodedPayload) // 返回我们的JWT对象以供后续使用 return &JWT{encodedHeader, string(dstPayload), signature}, nil }

我们构造一个用户的结构体

type UserInfo struct { Name string `json:”name”` Password string `json:”password”` }

我们这次使用123456作为密钥简单的验证一下

var Key []byte=[]byte(“12346”)

在此我们构造一个验证的中间件

func jwtConfirm(context *gin.Context) { // 登录不需要token if context.Request.RequestURI==”/login” { return } // 拿出token token :=context.GetHeader(“Token”) // 进行解析验证 jwt, err :=utils.ParseJwt(token, Key) if err !=nil { context.JSON(200, gin.H{ “msg”: err.Error(), }) // 有问题就流产掉(我也不知道怎么翻译好了,香蕉猫.jpg) context.Abort() } // 验证通过就将负载返回回去 context.JSON(200, gin.H{ “payload”: jwt.Payload, }) }

我们在此基础上就可以使用了,这边使用gin框架简单的测试一下

func main() { // 使用默认路由 router :=gin.Default() // 注册中间件 router.Use(jwtConfirm) // 简单做两个服务 router.POST(“/login”, func(context *gin.Context) { // 接收用户参数 var userInfo UserInfo=UserInfo{} // 使用jsonbind接收 bindErr :=context.ShouldBindJSON(&userInfo) if bindErr !=nil { context.JSON(200, gin.H{ “msg”: bindErr.Error(), }) } // 使用密钥做出token jwt, err :=utils.CreateJwt(Key, userInfo) if err !=nil { fmt.Println(err) } // 我们将token直接返回用于测试 context.JSON(200, gin.H{ “token”: jwt, }) }) router.GET(“/doing”) router.Run() }

image-20230429184039413.png

我们拿到了token

我们现在去试一下如果不带token的结果

image-20230429184135724.png

我们试一下携带错误token的情况

image-20230429184233619.png

我们最后测试一下正确的token

image-20230429184635149.png

在实际环境中会使用更复杂的情况进行使用(例如密钥会更加复杂,会在pyload中设置失效时间等等),但是生成token和解析token的操作和上述的操作差别不大

到此这篇关于golang原生实现JWT的示例代码的文章就介绍到这了,更多相关golang原生实现JWT内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:golang中的jwt使用教程流程分析Golang使用JWT进行认证和加密的示例详解Golang基于JWT与Casbin身份验证授权实例详解go语言使用jwt认证的实现go语言beego框架jwt身份认证实现示例Go语言中JWT的创建和解析操作详解