教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 JWT 在 Gin 中的使用

JWT 在 Gin 中的使用

发布时间:2021-12-04   编辑:jiaochengji.com
教程集为您提供JWT 在 Gin 中的使用等资源,欢迎您收藏本站,我们将为您提供最新的JWT 在 Gin 中的使用资源

原文:JWT 在 Gin 中的使用

<h2>介绍</h2>

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

<h2>使用</h2> <h3>安装</h3> <pre><code class="bash">go get github.com/appleboy/gin-jwt</code></pre>

引入

<pre><code class="go">import "github.com/appleboy/gin-jwt"</code></pre>

我目前使用的版本是 <code>v2.5.0</code>.

<!-- more -->

<h3>创建中间件</h3>

设计 API 对象

<pre><code class="go">type API struct { App *apps.App // 业务对象 Router *gin.Engine // 路由 JWT *jwt.GinJWTMiddleware // jwt 对象 }</code></pre>

中间件对象:

<pre><code class="go">api.JWT = &jwt.GinJWTMiddleware{ Realm: "gin jwt", Key: []byte("secret key"), Timeout: time.Hour, MaxRefresh: time.Hour, PayloadFunc: func(data interface{}) jwt.MapClaims {}, Authenticator: func(c *gin.Context) (interface{}, error) {}, Authorizator: func(data interface{}, c *gin.Context) bool {}, Unauthorized: func(c *gin.Context, code int, message string) {}, TokenLookup: "header: Authorization, query: token, cookie: jwt", // TokenLookup: "query:token", // TokenLookup: "cookie:token", TokenHeadName: "Bearer", TimeFunc: time.Now, }</code></pre> <ul><li> <code>Realm</code> JWT标识</li> <li> <code>Key</code> 服务端密钥</li> <li> <code>Timeout</code> token 过期时间</li> <li> <code>MaxRefresh</code> token 更新时间</li> <li> <code>PayloadFunc</code> 添加额外业务相关的信息</li> <li> <code>Authenticator</code> 在登录接口中使用的验证方法,并返回验证成功后的用户对象。</li> <li> <code>Authorizator</code> 登录后其他接口验证传入的 token 方法</li> <li> <code>Unauthorized</code> 验证失败后设置错误信息</li> <li> <code>TokenLookup</code> 设置 token 获取位置,一般默认在头部的 <code>Authorization</code> 中,或者 query的 token 字段,cookie 中的 jwt 字段。</li> <li> <code>TokenHeadName</code> Header中 token 的头部字段,默认常用名称 <code>Bearer</code>。</li> <li> <code>TimeFunc</code> 设置时间函数</li> </ul><h3>注册阶段</h3>

在注册时如果要直接返回 token,那么可以调用 <code>TokenGenerator</code> 来生成 token。

<pre><code class="go">token, expire, err := c.JWT.TokenGenerator(strconv.Itoa(user.ID), *user)</code></pre>

<code>TokenGenerator</code> 的具体实现

<pre><code class="go">func (mw *GinJWTMiddleware) TokenGenerator(userID string, data interface{}) (string, time.Time, error) { // 根据签名算法创建 token 对象 token := jwt.New(jwt.GetSigningMethod(mw.SigningAlgorithm)) // 获取 claims claims := token.Claims.(jwt.MapClaims) // 设置业务中需要的额外信息 if mw.PayloadFunc != nil { for key, value := range mw.PayloadFunc(data) { claims[key] = value } } // 过期时间 expire := mw.TimeFunc().UTC().Add(mw.Timeout) claims["id"] = userID claims["exp"] = expire.Unix() claims["orig_iat"] = mw.TimeFunc().Unix() // 生成 token tokenString, err := mw.signedString(token) if err != nil { return "", time.Time{}, err } return tokenString, expire, nil }</code></pre> <h3>登录阶段</h3>

登录时会调用 <code>Authenticator</code> 注册的方法。

<pre><code class="go">func (api *API) LoginAuthenticator(ctx *gin.Context) (interface{}, error) { var params model.UserParams if err := ctx.Bind(&params); err != nil { return "", jwt.ErrMissingLoginValues } // 根据用户名获取用户 user, err := api.App.GetUserByName(params.Username) if err != nil { return nil, err } // 验证密码 if user.AuthPassword(params.Password) { return *user, nil } return nil, jwt.ErrFailedAuthentication }</code></pre> <h3>验证 Token</h3>

其他接口在设置了中间件 <code>Router.Use(api.JWT.MiddlewareFunc())</code> 后,通过调用 <code>Authorizator</code> 方法来验证。

<pre><code class="go">func (api *API) LoginedAuthorizator(data interface{}, c *gin.Context) bool { if id, ok := data.(string); ok { return api.App.IsExistUser(id) } return false }</code></pre>

在业务 Hander 中可以通过方法 <code>jwt.ExtractClaims(ctx)</code> 来获取 payload 的信息。

<h2>深入</h2>

<code>gin-jwt</code> 依赖的 <code>jwt</code> 库叫做 <code>jwt-go</code>。下面来介绍一下这个库。

核心的 <code>Token</code> 结构:

<pre><code class="go">// A JWT Token. Different fields will be used depending on whether you're // creating or parsing/verifying a token. type Token struct { Raw string // The raw token. Populated when you Parse a token Method SigningMethod // The signing method used or to be used Header map[string]interface{} // The first segment of the token Claims Claims // The second segment of the token Signature string // The third segment of the token. Populated when you Parse a token Valid bool // Is the token valid? Populated when you Parse/Verify a token }</code></pre>

这个<code>Token</code>结构体是用来生成 <code>jwt</code> 的 token。其中 <code>Method</code> 是用来表示签名使用的算法。<code>Header</code> 是头部<code>jwt</code>的信息,还有 <code>Claims</code> 记录额外的信息。

然后是生成签名的方法,key 是服务端的密钥。

<pre><code class="go">func (t *Token) SignedString(key interface{}) (string, error) { var sig, sstr string var err error // 将 Header 和 Claims 转换成字符串然后 base64 之后拼接在一起。 if sstr, err = t.SigningString(); err != nil { return "", err } // 使用签名算法加密 if sig, err = t.Method.Sign(sstr, key); err != nil { return "", err } return strings.Join([]string{sstr, sig}, "."), nil }</code></pre>

解密 token 的对象叫做 <code>Parser</code>

<pre><code class="go">type Parser struct {} // 主要解析方法 func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {}</code></pre>

Parser 除了验证 Token 外,还包括解码 Header 和 Claims 的内容。

<h2>资源</h2> <ul><li>https://jwt.io/introduction</li> <li>https://github.com/appleboy/g...</li> <li>https://github.com/dgrijalva/...</li> </ul> 到此这篇关于“JWT 在 Gin 中的使用”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
JWT 在 Gin 中的使用
基于golang语言web框架gin搭建应用-02配置文件(yml)
Golang 实现JWT认证
Gin 框架绑定 JSON 参数使用 jsoniter
JWT Token认证
JWT实现用户认证原理与实现(golang)
gin定义统一处理错误
Golang pprof 性能分析与火焰图
golang 字符串分割_Golang 微服务教程(四)
gin-vue-admin 使用 go mod , golang开发工具 提示package gin-vue-admin/core is not in GOROOT

上一篇:golang无缓冲通道 下一篇:golang 数学函数
[关闭]
~ ~