婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 基于gin的golang web開發(fā)之認(rèn)證利器jwt

基于gin的golang web開發(fā)之認(rèn)證利器jwt

熱門標(biāo)簽:赤峰電銷 利用地圖標(biāo)注位置 貴州電話智能外呼系統(tǒng) 地圖區(qū)域圖標(biāo)注后導(dǎo)出 杭州人工智能電銷機(jī)器人費(fèi)用 谷歌美發(fā)店地圖標(biāo)注 官渡電銷外呼管理系統(tǒng)怎么收費(fèi) 江蘇呼叫中心外呼系統(tǒng)有效果嗎 400開頭電話怎樣申請

JSON Web Token(JWT)是一種很流行的跨域認(rèn)證解決方案,JWT基于JSON可以在進(jìn)行驗(yàn)證的同時附帶身份信息,對于前后端分離項(xiàng)目很有幫助。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

JWT由三部分組成,每個部分之間用點(diǎn).隔開,分別稱為HEADER、PAYLOAD和VERIFY SIGNATURE。HEADER和PAYLOAD經(jīng)過base64解碼后為JSON明文。

  1. HEADER包含兩個字段,alg指明JWT的簽名算法,typ固定為JWT。
  2. PAYLOAD中包含JWT的聲明信息,標(biāo)準(zhǔn)中定義了iss、sub、aud等聲明字段,如果標(biāo)準(zhǔn)聲明不夠用的話,我們還可以增加自定義聲明。要注意兩點(diǎn),第一PAYLOAD只是經(jīng)過base64編碼,幾乎就等于是明文,不要包含敏感信息。第二不要在PAYLOAD中放入過多的信息,因?yàn)轵?yàn)證通過以后每一個請求都要包含JWT,信息太多的話會造成一些沒有必要的資源浪費(fèi)。
  3. VERIFY SIGNATURE為使用HEADER中指定的算法生成的簽名。例如alg:HS256簽名算法

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload),密鑰)

了解完JWT的基本原理之后,我們來看一下在gin中是怎么使用JWT的。

引入gin-jwt中間件

在Gin中使用jwt有個開源項(xiàng)目gin-jwt,這項(xiàng)目幾乎包含了我們要用到的一切。例如定義PAYLOAD中的聲明、授權(quán)驗(yàn)證的方法、是否使用COOKIE等等。下面來看一下官網(wǎng)給出的例子。

package main

import (
	"log"
	"net/http"
	"os"
	"time"

	jwt "github.com/appleboy/gin-jwt/v2"
	"github.com/gin-gonic/gin"
)

type login struct {
	Username string `form:"username" json:"username" binding:"required"`
	Password string `form:"password" json:"password" binding:"required"`
}

var identityKey = "id"

func helloHandler(c *gin.Context) {
	claims := jwt.ExtractClaims(c)
	user, _ := c.Get(identityKey)
	c.JSON(200, gin.H{
		"userID":  claims[identityKey],
		"userName": user.(*User).UserName,
		"text":   "Hello World.",
	})
}

type User struct {
	UserName string
	FirstName string
	LastName string
}

func main() {
	port := os.Getenv("PORT")
	r := gin.New()
	r.Use(gin.Logger())
	r.Use(gin.Recovery())

	if port == "" {
		port = "8000"
	}

	authMiddleware, err := jwt.New(jwt.GinJWTMiddleware{
		Realm:    "test zone",
		Key:     []byte("secret key"),
		Timeout:   time.Hour,
		MaxRefresh: time.Hour,
		IdentityKey: identityKey,
		PayloadFunc: func(data interface{}) jwt.MapClaims {
			if v, ok := data.(*User); ok {
				return jwt.MapClaims{
					identityKey: v.UserName,
				}
			}
			return jwt.MapClaims{}
		},
		IdentityHandler: func(c *gin.Context) interface{} {
			claims := jwt.ExtractClaims(c)
			return User{
				UserName: claims[identityKey].(string),
			}
		},
		Authenticator: func(c *gin.Context) (interface{}, error) {
			var loginVals login
			if err := c.ShouldBind(loginVals); err != nil {
				return "", jwt.ErrMissingLoginValues
			}
			userID := loginVals.Username
			password := loginVals.Password

			if (userID == "admin"  password == "admin") || (userID == "test"  password == "test") {
				return User{
					UserName: userID,
					LastName: "Bo-Yi",
					FirstName: "Wu",
				}, nil
			}

			return nil, jwt.ErrFailedAuthentication
		},
		Authorizator: func(data interface{}, c *gin.Context) bool {
			if v, ok := data.(*User); ok  v.UserName == "admin" {
				return true
			}

			return false
		},
		Unauthorized: func(c *gin.Context, code int, message string) {
			c.JSON(code, gin.H{
				"code":  code,
				"message": message,
			})
		},

		TokenLookup: "header: Authorization, query: token, cookie: jwt",
		TokenHeadName: "Bearer",
		TimeFunc: time.Now,
	})

	if err != nil {
		log.Fatal("JWT Error:" + err.Error())
	}

	errInit := authMiddleware.MiddlewareInit()

	if errInit != nil {
		log.Fatal("authMiddleware.MiddlewareInit() Error:" + errInit.Error())
	}

	r.POST("/login", authMiddleware.LoginHandler)

	r.NoRoute(authMiddleware.MiddlewareFunc(), func(c *gin.Context) {
		claims := jwt.ExtractClaims(c)
		log.Printf("NoRoute claims: %#v\n", claims)
		c.JSON(404, gin.H{"code": "PAGE_NOT_FOUND", "message": "Page not found"})
	})

	auth := r.Group("/auth")
	auth.GET("/refresh_token", authMiddleware.RefreshHandler)
	auth.Use(authMiddleware.MiddlewareFunc())
	{
		auth.GET("/hello", helloHandler)
	}

	if err := http.ListenAndServe(":"+port, r); err != nil {
		log.Fatal(err)
	}
}

我們可以看到j(luò)wt.GinJWTMiddleware用于聲明一個中間件。PayloadFunc方法中給默認(rèn)的PAYLOAD增加了id字段,取值為UserName。Authenticator認(rèn)證器,我們可以在這里驗(yàn)證用戶身份,參數(shù)為*gin.Context,所以在這里我們可以像寫Gin Handler那樣獲取到Http請求中的各種內(nèi)容。Authorizator授權(quán)器可以判斷判斷當(dāng)前JWT是否有權(quán)限繼續(xù)訪問。當(dāng)然還可以設(shè)置像過期時間,密鑰,是否設(shè)置COOKIE等其他選項(xiàng)。

登錄Handler

以上例子中配置了路由r.POST("/login", authMiddleware.LoginHandler)下面我們來看一下登錄過程是怎樣的。

func (mw *GinJWTMiddleware) LoginHandler(c *gin.Context) {
	if mw.Authenticator == nil {
		mw.unauthorized(c, http.StatusInternalServerError, mw.HTTPStatusMessageFunc(ErrMissingAuthenticatorFunc, c))
		return
	}

	data, err := mw.Authenticator(c)

	if err != nil {
		mw.unauthorized(c, http.StatusUnauthorized, mw.HTTPStatusMessageFunc(err, c))
		return
	}

	// Create the token
	token := jwt.New(jwt.GetSigningMethod(mw.SigningAlgorithm))
	claims := token.Claims.(jwt.MapClaims)

	if mw.PayloadFunc != nil {
		for key, value := range mw.PayloadFunc(data) {
			claims[key] = value
		}
	}

	expire := mw.TimeFunc().Add(mw.Timeout)
	claims["exp"] = expire.Unix()
	claims["orig_iat"] = mw.TimeFunc().Unix()
	tokenString, err := mw.signedString(token)

	if err != nil {
		mw.unauthorized(c, http.StatusUnauthorized, mw.HTTPStatusMessageFunc(ErrFailedTokenCreation, c))
		return
	}

	// set cookie
	if mw.SendCookie {
		expireCookie := mw.TimeFunc().Add(mw.CookieMaxAge)
		maxage := int(expireCookie.Unix() - mw.TimeFunc().Unix())

		if mw.CookieSameSite != 0 {
			c.SetSameSite(mw.CookieSameSite)
		}

		c.SetCookie(
			mw.CookieName,
			tokenString,
			maxage,
			"/",
			mw.CookieDomain,
			mw.SecureCookie,
			mw.CookieHTTPOnly,
		)
	}

	mw.LoginResponse(c, http.StatusOK, tokenString, expire)
}

LoginHandler整體邏輯還是比較簡單的,檢查并調(diào)用前面設(shè)置的Authenticator方法,驗(yàn)證成功的話生成一個新的JWT,調(diào)用PayloadFunc方法設(shè)置PAYLOAD的自定義字段,根據(jù)SendCookie判斷是否需要在HTTP中設(shè)置COOKIE,最后調(diào)用LoginResponse方法設(shè)置返回值。

使用中間件

jwt-gin包提供了一個標(biāo)準(zhǔn)的Gin中間件,我們可以在需要驗(yàn)證JWT的路由上設(shè)置中間件。前面例子中對路由組/auth增加了JWT驗(yàn)證auth.Use(authMiddleware.MiddlewareFunc())

func (mw *GinJWTMiddleware) MiddlewareFunc() gin.HandlerFunc {
	return func(c *gin.Context) {
		mw.middlewareImpl(c)
	}
}

func (mw *GinJWTMiddleware) middlewareImpl(c *gin.Context) {
	claims, err := mw.GetClaimsFromJWT(c)
	if err != nil {
		mw.unauthorized(c, http.StatusUnauthorized, mw.HTTPStatusMessageFunc(err, c))
		return
	}

	if claims["exp"] == nil {
		mw.unauthorized(c, http.StatusBadRequest, mw.HTTPStatusMessageFunc(ErrMissingExpField, c))
		return
	}

	if _, ok := claims["exp"].(float64); !ok {
		mw.unauthorized(c, http.StatusBadRequest, mw.HTTPStatusMessageFunc(ErrWrongFormatOfExp, c))
		return
	}

	if int64(claims["exp"].(float64))  mw.TimeFunc().Unix() {
		mw.unauthorized(c, http.StatusUnauthorized, mw.HTTPStatusMessageFunc(ErrExpiredToken, c))
		return
	}

	c.Set("JWT_PAYLOAD", claims)
	identity := mw.IdentityHandler(c)

	if identity != nil {
		c.Set(mw.IdentityKey, identity)
	}

	if !mw.Authorizator(identity, c) {
		mw.unauthorized(c, http.StatusForbidden, mw.HTTPStatusMessageFunc(ErrForbidden, c))
		return
	}

	c.Next()
}

GetClaimsFromJWT方法在當(dāng)前上下文中獲取JWT,失敗的話返回未授權(quán)。接著會判斷JWT是否過期,最后前面設(shè)置的Authorizator方法驗(yàn)證是否有權(quán)限繼續(xù)訪問。

到此這篇關(guān)于基于gin的golang web開發(fā)之認(rèn)證利器jwt的文章就介紹到這了,更多相關(guān)gin的golang web開發(fā)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Gin golang web開發(fā)模型綁定實(shí)現(xiàn)過程解析
  • 基于gin的golang web開發(fā):路由示例詳解
  • golang websocket 服務(wù)端的實(shí)現(xiàn)
  • Golang實(shí)現(xiàn)web文件共享服務(wù)的示例代碼
  • golang搭建靜態(tài)web服務(wù)器的實(shí)現(xiàn)方法
  • golang基于websocket實(shí)現(xiàn)的簡易聊天室程序

標(biāo)簽:松原 泰安 黔西 鷹潭 武漢 保定 宜春 河池

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《基于gin的golang web開發(fā)之認(rèn)證利器jwt》,本文關(guān)鍵詞  基于,gin,的,golang,web,開,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《基于gin的golang web開發(fā)之認(rèn)證利器jwt》相關(guān)的同類信息!
  • 本頁收集關(guān)于基于gin的golang web開發(fā)之認(rèn)證利器jwt的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    麻豆久久久久久| 全国精品久久少妇| 亚洲女女做受ⅹxx高潮| 99久久免费国产| 成人免费在线视频观看| 日本乱码高清不卡字幕| 亚洲精选在线视频| 色一情一乱一乱一91av| 一区二区三区四区亚洲| 欧美人狂配大交3d怪物一区| 日本一区中文字幕| 精品国产乱码久久久久久免费 | 一色屋精品亚洲香蕉网站| 成人app软件下载大全免费| 亚洲图片欧美激情| 欧美高清视频一二三区| 国产激情一区二区三区桃花岛亚洲| 久久久精品tv| 欧日韩精品视频| 麻豆精品久久久| 国产午夜精品福利| 欧美丝袜丝交足nylons| 国产一区二区三区av电影 | 国产高清成人在线| 国产精品国产三级国产a| 欧美日本乱大交xxxxx| 激情五月播播久久久精品| 国产精品午夜春色av| 在线观看91av| 成人国产免费视频| 亚洲精品亚洲人成人网在线播放| 欧美日韩在线不卡| 国产高清不卡二三区| 亚洲亚洲人成综合网络| 久久久久亚洲综合| 欧美伊人久久久久久久久影院| 国产精品99久久久久久宅男| 亚洲欧美日韩一区二区三区在线观看| 日韩丝袜美女视频| 99视频在线精品| 日本免费新一区视频| 亚洲欧美日本在线| 国产精品久久久久久久浪潮网站| 欧美一区二区三区免费大片| 99国产麻豆精品| 精品一区二区三区欧美| 亚洲一级二级在线| 国产精品国产精品国产专区不蜜| 日韩欧美国产三级| 欧美日韩专区在线| 在线一区二区三区| 色婷婷亚洲一区二区三区| 成人白浆超碰人人人人| 韩国中文字幕2020精品| 韩国女主播成人在线| 免费国产亚洲视频| 青青草一区二区三区| 日韩电影在线一区二区三区| 亚洲成av人片www| 亚洲va国产va欧美va观看| 一区二区久久久久久| 亚洲裸体在线观看| 亚洲国产精品成人久久综合一区| 久久精品人人做人人综合| 欧美一级一区二区| 欧美精品久久天天躁| 欧美日韩综合在线免费观看| 欧美日韩一区视频| 欧美日韩一区二区三区视频| 欧美日韩在线观看一区二区 | 国产99精品国产| 久久精品99久久久| 亚洲国产中文字幕| 亚洲国产精品麻豆| 日韩精品电影在线观看| 五月天婷婷综合| 日本视频一区二区| 国产精品一区二区在线观看不卡 | 亚洲视频免费在线观看| 欧美一区二区网站| 国产精品福利一区二区| 9i在线看片成人免费| 国产真实乱对白精彩久久| 国产成人av在线影院| 国产成人av福利| av激情综合网| 欧美日韩精品一二三区| 欧美日本不卡视频| 精品国产伦一区二区三区观看方式| 久久精品无码一区二区三区| 一区在线播放视频| 亚欧色一区w666天堂| 国产精品一级二级三级| 91豆麻精品91久久久久久| 欧美猛男gaygay网站| 日韩一级二级三级精品视频| 国产欧美日韩不卡| 亚洲欧美日韩人成在线播放| 日本va欧美va精品发布| 国产精品资源在线观看| 欧洲国内综合视频| 精品国精品国产尤物美女| 亚洲精品高清在线观看| 国模娜娜一区二区三区| 欧美色男人天堂| 日韩三级视频中文字幕| 国产精品网站在线播放| 久久精品999| 欧美亚洲一区二区三区四区| 国产香蕉久久精品综合网| 性做久久久久久免费观看| 99久久精品免费看| 国产亚洲欧美激情| 奇米影视在线99精品| 色综合天天综合网天天看片| 欧美精品一区二区三区久久久| 亚洲午夜三级在线| 91色porny蝌蚪| 欧美韩日一区二区三区四区| 欧美精品久久99久久在免费线| 国产精品国产成人国产三级 | 国产欧美精品区一区二区三区 | 无吗不卡中文字幕| jlzzjlzz国产精品久久| 精品国产乱码久久久久久久久| 亚洲成人激情社区| 色综合欧美在线视频区| 欧美精品一区二区三| 日本欧美一区二区在线观看| 波多野结衣中文一区| 国产精品全国免费观看高清 | 成人av电影在线| 欧美日韩精品专区| 岛国精品在线观看| 久久久久久久久久久久久女国产乱| 日韩制服丝袜av| 一本一道综合狠狠老| 国产精品不卡视频| 国产91精品入口| 国产精品天干天干在观线| 国产成人精品亚洲日本在线桃色 | 日韩欧美国产小视频| 蜜臀精品久久久久久蜜臀| 欧美一区二区三区精品| 久久精品国产色蜜蜜麻豆| 欧美电视剧免费观看| 国产一区三区三区| 粉嫩欧美一区二区三区高清影视 | 捆绑调教美女网站视频一区| 欧美日韩精品系列| 日本欧美加勒比视频| 欧美大胆一级视频| 国产视频一区在线观看| 老色鬼精品视频在线观看播放| 7777精品伊人久久久大香线蕉| 亚洲国产精品久久人人爱| 91豆麻精品91久久久久久| 午夜日韩在线观看| 91精品视频网| 日精品一区二区| 欧美日韩国产精品成人| 污片在线观看一区二区| 91麻豆精品国产91久久久| 蜜臀99久久精品久久久久久软件| 56国语精品自产拍在线观看| 日韩成人免费看| 久久久一区二区三区捆绑**| 国产精品1区2区| 亚洲免费电影在线| 欧美一区国产二区| 国产呦萝稀缺另类资源| 亚洲同性gay激情无套| 欧美一区二区三区喷汁尤物| 国产乱色国产精品免费视频| 国产精品国产三级国产aⅴ原创| 白白色亚洲国产精品| 亚洲六月丁香色婷婷综合久久| 欧美亚洲一区三区| 国产ts人妖一区二区| 一区二区在线观看av| 日韩美女视频在线| av在线一区二区三区| 午夜精品福利一区二区蜜股av| 欧美老人xxxx18| 91亚洲精品久久久蜜桃| 狠狠色综合色综合网络| 亚州成人在线电影| 亚洲欧美国产毛片在线| 久久久久久久久久久久久女国产乱| 欧美精品日韩一本| 欧美伊人精品成人久久综合97| 成人国产精品视频| 九九九久久久精品| 免费人成精品欧美精品| 亚洲一区二区三区在线播放| 国产精品久久久久影视| 久久久亚洲综合| 欧美本精品男人aⅴ天堂| 欧美日韩日日摸| 在线观看视频一区|