<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
JWT全稱JSON Web Token是一種跨域認證解決方案,屬於一個開放的標準,它規定了一種Token實現方式,目前多用於前後端分離專案和OAuth3.0業務場景下。
在之前的一些web專案中,我們通常使用的是Cookie-Session
模式實現使用者認證。相關流程大致如下:
這種方案依賴於使用者端(瀏覽器)儲存Cookie,並且需要在伺服器端儲存使用者的session資料。
在行動網際網路時代,我們的使用者可能使用瀏覽器也可能使用APP來存取我們的服務,我們的web應用可能是前後端分開部署在不同的埠,有時候我們還需要支援第三方登入,這下Cookie-Session
的模式就有些力不從心了。
JWT就是一種基於Token的輕量級認證模式,伺服器端認證通過後,會生成一個JSON物件,經過簽名後得到一個Token(令牌)再發回給使用者,使用者後續請求只需要帶上這個Token,伺服器端解密之後就能獲取該使用者的相關資訊了。
想要連線JWT的原理,推薦大家閱讀:JWT入門教學
我們在這裡直接使用jwt-go
這個庫來實現我們生成JWT和解析JWT的功能。
我們需要客製化自己的需求來決定JWT中儲存哪些資料,比如我們規定在JWT中要儲存username
資訊,那麼我們就定義一個MyClaims
結構體如下:
import ( "github.com/dgrijalva/jwt-go" ) // MyClaims 自定義宣告結構體並內嵌jwt.StandardClaims // jwt包自帶的jwt.StandardClaims只包含了官方欄位 // 我們這裡需要額外記錄一個username欄位,所以要自定義結構體 // 如果想要儲存更多資訊,都可以新增到這個結構體中 type MyClaims struct { Username string `json:"username"` jwt.StandardClaims }
然後我們定義JWT的過期時間,這裡以2小時為例:
const TokenExpireDuration = time.Hour * 2
接下來還需要定義Secret:
var MySecret = []byte("夏天夏天悄悄過去")
// GenToken 生成JWT func GenToken(username string) (string, error) { // 建立一個我們自己的宣告 c := MyClaims{ "username", // 自定義欄位 jwt.StandardClaims{ ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), // 過期時間 Issuer: "my-project", // 簽發人 }, } // 使用指定的簽名方法建立簽名物件 token := jwt.NewWithClaims(jwt.SigningMethodHS256, c) // 使用指定的secret簽名並獲得完整的編碼後的字串token return token.SignedString(MySecret) }
// ParseToken 解析JWT func ParseToken(tokenString string) (*MyClaims, error) { // 解析token token, err := jwt.ParseWithClaims(tokenString, &MyClaims{}, func(token *jwt.Token) (i interface{}, err error) { return MySecret, nil }) if err != nil { return nil, err } if claims, ok := token.Claims.(*MyClaims); ok && token.Valid { // 校驗token return claims, nil } return nil, errors.New("invalid token") }
首先我們註冊一條路由/auth
,對外提供獲取Token的渠道:
r.POST("/auth", authHandler)
我們的authHandler
定義如下:
func authHandler(c *gin.Context) { // 使用者傳送使用者名稱和密碼過來 var user UserInfo err := c.ShouldBind(&user) if err != nil { c.JSON(http.StatusOK, gin.H{ "code": 2001, "msg": "無效的引數", }) return } // 校驗使用者名稱和密碼是否正確 if user.Username == "q1mi" && user.Password == "q1mi123" { // 生成Token tokenString, _ := GenToken(user.Username) c.JSON(http.StatusOK, gin.H{ "code": 2000, "msg": "success", "data": gin.H{"token": tokenString}, }) return } c.JSON(http.StatusOK, gin.H{ "code": 2002, "msg": "鑑權失敗", }) return }
使用者通過上面的介面獲取Token之後,後續就會攜帶著Token再來請求我們的其他介面,這個時候就需要對這些請求的Token進行校驗操作了,很顯然我們應該實現一個檢驗Token的中介軟體,具體實現如下:
// JWTAuthMiddleware 基於JWT的認證中介軟體 func JWTAuthMiddleware() func(c *gin.Context) { return func(c *gin.Context) { // 使用者端攜帶Token有三種方式 1.放在請求頭 2.放在請求體 3.放在URI // 這裡假設Token放在Header的Authorization中,並使用Bearer開頭 // 這裡的具體實現方式要依據你的實際業務情況決定 authHeader := c.Request.Header.Get("Authorization") if authHeader == "" { c.JSON(http.StatusOK, gin.H{ "code": 2003, "msg": "請求頭中auth為空", }) c.Abort() return } // 按空格分割 parts := strings.SplitN(authHeader, " ", 2) if !(len(parts) == 2 && parts[0] == "Bearer") { c.JSON(http.StatusOK, gin.H{ "code": 2004, "msg": "請求頭中auth格式有誤", }) c.Abort() return } // parts[1]是獲取到的tokenString,我們使用之前定義好的解析JWT的函數來解析它 mc, err := ParseToken(parts[1]) if err != nil { c.JSON(http.StatusOK, gin.H{ "code": 2005, "msg": "無效的Token", }) c.Abort() return } // 將當前請求的username資訊儲存到請求的上下文c上 c.Set("username", mc.Username) c.Next() // 後續的處理常式可以用過c.Get("username")來獲取當前請求的使用者資訊 } }
註冊一個/home
路由,發個請求驗證一下吧。
r.GET("/home", JWTAuthMiddleware(), homeHandler) func homeHandler(c *gin.Context) { username := c.MustGet("username").(string) c.JSON(http.StatusOK, gin.H{ "code": 2000, "msg": "success", "data": gin.H{"username": username}, }) }
如果不想自己實現上述功能,你也可以使用Github上別人封裝好的包。
以上就是gin框架中使用JWT的定義需求及解析的詳細內容,更多關於gin框架中使用JWT的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45