当前位置:网站首页>Go language uses JWT
Go language uses JWT
2022-06-22 05:44:00 【weixin_ forty-six million two hundred and seventy-two thousand 】
Go Language use JWT
We know there are cookie and session To verify the method of user login , But this is too cumbersome and stores a lot of data . We can use token Method to authenticate .
The user sends data to the backend , The back end uses the data to form a complex string by encrypting and signing , We can call it a token . The server then gives the token to the client , In the future, the client will bring this token every time it accesses , Then the server checks whether the token exists or whether the token has expired , The client can only access after passing the verification .
Generate JWT
Define incoming information
Generate token Need user specific information , We can customize the structure , Add the information you want . among jwt.StandardClaims Is an official field .
// MyClaims Customize the declaration structure and embed jwt.StandardClaims
// jwt It comes with you jwt.StandardClaims Only official fields are included
// We need to record an additional username Field , So you need to customize the structure
// If you want to save more information , Can be added to this structure
type MyClaims struct {
UserID uint64 `json:"user_id"`
Username string `json:"username"`
jwt.StandardClaims
}
Our tokens have an expiration date , So we need to define JWT The expiration time of
const TokenExpireDuration = time.Hour * 2
Next, you need to define Secret:
var MySecret = []byte("syz")
Generate JWT
- Custom structure
- Pass in the structure and signature method , Create signature object
- Finally, sign the token , Get the complete signature token
// GenToken Generate JWT
func GenToken(userID uint64, username string) (string, error) {
// Create our own declared data
c := MyClaims{
userID,
"username", // Custom field
jwt.StandardClaims{
ExpiresAt: time.Now().Add( // Note here INT Not directly with time.hour Multiply , So use time.duration Change my
time.Duration(viper.GetInt("auth.jet_expire")) * time.Hour).Unix(), // Expiration time
Issuer: "bluebell", // Issued by people
},
}
// Creates a signature object using the specified signature method
token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
// Use specified secret Sign and get the complete encoded string token
return token.SignedString(mySecret)
}
analysis JWT
// ParseToken analysis JWT
func ParseToken(tokenString string) (*MyClaims, error) {
// analysis token
token, err := jwt.ParseWithClaims(tokenString, &MyClaims{
}, func(token *jwt.Token) (i interface{
}, err error) {
return MySecret, nil
})
if err != nil {
return nil, err
}
// The token is valid
if claims, ok := token.Claims.(*MyClaims); ok && token.Valid {
// check token
return claims, nil
}
return nil, errors.New("invalid token")
}
Research function
We can observe the details of the following code , Create a signature object using a signature method
token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
This is a NewWithClaims function , It can be seen that it needs to get an encryption method and a structure containing information . Then use this information to initialize a Token , And return its pointer .
func NewWithClaims(method SigningMethod, claims Claims) *Token {
return &Token{
Header: map[string]interface{
}{
"typ": "JWT",
"alg": method.Alg(),
},
Claims: claims,
Method: method,
}
We can observe the Token The information contained .
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
}
- Raw: The original token
- Method: Signature method used or to be used
- Header: The first paragraph of the token
- Claims: Second segment of token
- Signature: The third paragraph of the token ( When parsing the token, fill in )
- Valid: Is the token valid ( When parsing the token, fill in )
Finally, sign the token , Get the complete signature token
func (t *Token) SignedString(key interface{
}) (string, error) {
var sig, sstr string
var err error
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
}
stay Gin Use... In the framework JWT
First, we register a route /auth, Provide access to the outside world Token Channel of :
r.POST("/auth", authHandler)
our authHandler The definition is as follows :
func authHandler(c *gin.Context) {
// The user sends the user name and password
var user UserInfo
err := c.ShouldBind(&user)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": 2001,
"msg": " Invalid parameter ",
})
return
}
// Verify that the user name and password are correct ( If it is correct, it returns token)
if user.Username == "q1mi" && user.Password == "q1mi123" {
// Generate 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": " Authentication failure ",
})
return
}
The user obtains... Through the above interface Token after , Then you'll carry Token Then ask for our other interfaces , At this time, we need to respond to these requests Token The verification operation has been carried out , Obviously, we should implement a test Token Middleware , The specific implementation is as follows :
// JWTAuthMiddleware be based on JWT Authentication middleware for
func JWTAuthMiddleware() func(c *gin.Context) {
return func(c *gin.Context) {
// The client carries Token There are three ways 1. Put it on the request 2. Put in request body 3. Put it in URI
// It is assumed that Token Put it in Header Of Authorization in , And use Bearer start
// The specific implementation method here should be determined according to your actual business situation
authHeader := c.Request.Header.Get("Authorization")
if authHeader == "" {
c.JSON(http.StatusOK, gin.H{
"code": 2003,
"msg": " Request header auth It's empty ",
})
c.Abort()
return
}
// Split by space
parts := strings.SplitN(authHeader, " ", 2)
if !(len(parts) == 2 && parts[0] == "Bearer") {
c.JSON(http.StatusOK, gin.H{
"code": 2004,
"msg": " Request header auth Wrong format ",
})
c.Abort()
return
}
// parts[1] It's got tokenString, We use the previously defined parsing JWT To parse it
mc, err := ParseToken(parts[1])
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": 2005,
"msg": " invalid Token",
})
c.Abort()
return
}
// Will the currently requested username Save the information to the context of the request c On
c.Set("username", mc.Username)
c.Next() // Subsequent processing functions can be used c.Get("username") To get the currently requested user information
}
}
Sign up for a /home route , Send a request to verify .
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},
})
}
Reference resources
边栏推荐
- Innosetup method for judging that the program has run
- 关于二分一些模板
- tmux -- ssh terminal can be closed without impact the server process
- Hide symbol of dynamic library
- Prompt box moving with the mouse
- The "decentralization" mode of independent stations has risen, sweeping the tide of cross-border enterprise transformation
- 记录在处理SIF数据中,遇到的一些问题及解决过程
- QEMU ARM interrupt system architecture 2
- 数据的存储(进阶)
- Parameter serialization
猜你喜欢
随机推荐
SCM future employment development direction, learn SCM must know some entry-level knowledge and industry prospects, read the benefit
数据的存储(进阶)
Leetcode hot1-50
北峰助力南昌市应急管理局打造公专融合应急通信保障网
Shenzhen Nanshan District specialized special new small giant enterprise declaration index, with a subsidy of 500000 yuan
Want to put Facebook ads but don't know where to start? This article takes you to know more about
中小企业签署ERP合同时,需要留意这几点
Go语言使用JWT
《MATLAB 神经网络43个案例分析》:第28章 决策树分类器的应用研究——乳腺癌诊断
从“ 平台转型 ”到“ DTC品牌出海 ”,2021趋势何在?
\[\e]0;\[email protected]\h: \w\a\]\[\033[01;32m\]\[email protected]\h\[\033[0
错误:note: module requires Go 1.17
sourcetree报错ssh失败
Independent station optimization list - how to effectively improve the conversion rate in the station?
Zhiyuan OA vulnerability analysis, utilization and protection collection
Detailed explanation of OpenCV function usage 11~20, including code examples
Wanzi detailed data warehouse, data lake, data middle platform and lake warehouse are integrated
Global and Chinese silicon carbide barrier Schottky diode market demand and future prospect report 2022-2027
关于背包问题的总结
The "decentralization" mode of independent stations has risen, sweeping the tide of cross-border enterprise transformation



![P1061 [NOIP2006 普及组] Jam 的计数法](/img/53/7ca41b2ed4084f49ebcc2dd47e5919.png)



