首页  >  文章  >  后端开发  >  在 Go (Golang) 中实现 JWT 身份验证的分步指南

在 Go (Golang) 中实现 JWT 身份验证的分步指南

Linda Hamilton
Linda Hamilton原创
2024-11-19 20:48:03564浏览

在创建网站后端时,我们听到的一个非常重要的术语是 JWT 身份验证。 JWT 身份验证是保护 API 安全的最流行方法之一。 JWT 代表 JSON Web Token,它是一个开放标准,定义了一种在各方之间以 JSON 对象的形式传输信息的方式,并且非常安全。在本文中,我们将讨论 JWT 身份验证,最重要的是,我们将使用 Gin-Gonic 创建一个用于快速高效 JWT 身份验证的整个项目,这将是一个分步项目教程,将帮助您创建一个非常快速且行业性的项目。用于您的网站或应用程序后端的级身份验证 API。

目录:

  • 什么是 JWT 身份验证?
  • 项目结构
  • 先决条件
  • 分步教程
  • 最终结果
  • 输出
  • 结论

什么是 JWT 身份验证?

JWT 代表 JSON Web Token,它是一个开放标准,定义了一种在各方之间作为 JSON 对象传输信息的方式,并且非常安全。

让我们尝试通过一个例子来理解这一点。考虑这样一种情况:当我们出现在酒店时,我们走到前台,接待员说“嘿,我能为您做什么?”。我会说“嗨,我的名字是 Shubham,我来这里参加一个会议,赞助商正在支付我的酒店费用”。接待员说“好吧,太好了!好吧,我需要看几件事”。通常他们需要查看我的身份证明,以便证明我是谁,一旦他们确认我是正确的人,他们就会给我发一把钥匙。身份验证的工作方式与此示例非常相似。

通过 JWT 身份验证,我们向服务器发出请求,说“嘿!这是我的用户名和密码或登录令牌”,网站说“好的,让我检查一下”。如果我的用户名和密码正确,那么就会给我一个令牌。现在,在服务器的后续请求中,我不再需要包含我的用户名和密码。我只需携带我的令牌并入住酒店(网站),访问健身房(数据),我可以访问游泳池(信息),并且只能访问我的酒店房间(帐户),我无权访问任何其他酒店房间(其他用户的帐户)。该令牌仅在我的状态期间(从入住时间到结账时间)授权。之后就没有用了。现在,酒店还将允许未经任何验证的人至少看到酒店,在酒店周围的公共区域漫游,直到您进入酒店内,同样,作为匿名用户,您可以与网站的主页、登陆页面进行交互等等

这是 JWT 的示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ 
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

项目结构

这是该项目的结构。确保在您的工作区中也创建类似的文件夹结构。在此结构中,我们有 6 个文件夹:

  1. 控制器
  2. 数据库
  3. 帮手
  4. 中间件
  5. 模型
  6. 路线

并在这些文件夹中创建相应的文件。

Step-by-Step Guide to Implementing JWT Authentication in Go (Golang)

先决条件

  1. Go - 版本 1.18
  2. Mongo 数据库
  3. 分步教程

第 1 步. 让我们通过创建一个模块来启动项目,我的模块名称是“jwt”,我的用户名是“1shubham7”,因此我将通过输入以下内容来初始化我的模块:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ 
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

这将创建一个 go.mod 文件。

步骤 2. 创建一个 main.go 文件,让我们在 main.go 中创建一个 Web 服务器。为此,请在文件中添加以下代码:

go mod init github.com/1shubham7/jwt

用于检索环境变量的“os”包。
我们正在使用 gin-gonic 包来创建一个 Web 服务器。
稍后我们将创建一个路由包。
AuthRoutes()、UserRoutes()是routes包中文件内的函数,我们稍后将创建它。

第3步.下载gin-gonic包:

package main
import(
    "github.com/gin-gonic/gin"
    "os"
    routes "github.com/1shubham7/jwt/routes"
    "github.com/joho/godotenv"
    "log"
)
func main() {
    err := godotenv.Load(".env")
    if err != nil {
        log.Fatal("Error locading the .env file")
    }
    port := os.Getenv("PORT")
    if port == "" {
        port = "1111"
    }
    router := gin.New()
    router.Use(gin.Logger())
    routes.AuthRoutes(router)
    routes.UserRoutes(router)
    // creating two APIs
    router.GET("/api-1", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-1"})
    })
    router.GET("api-2", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-2"})
    })
    router.Run(":" + port)
}

步骤 4. 创建一个 models 文件夹并在其中创建一个 userModel.go 文件。在 userModel.go 中输入以下代码:

go get github.com/gin-gonic/gin

我们创建了一个名为 User 的结构,并向该结构添加了必要的字段。

json:"first_name" validate:"required, min=2, max=100" 这称为字段标签,这些在将 go 代码解码和编码为 JSON 和 JSON to go 期间使用。
这里 validate:"required, min=2, max=100" 用于验证特定字段必须至少有 2 个字符,最多 100 个字符。

第5步.创建一个数据库文件夹,并在其中创建一个databaseConnection.go文件,在其中输入以下代码:

package models
import (
    "go.mongodb.org/mongo-driver/bson/primitive"
    "time"
)
type User struct {
    ID            primitive.ObjectID `bson:"id"`
    First_name    *string            `json:"first_name" validate:"required, min=2, max=100"`
    Last_name     *string            `json:"last_name" validate:"required, min=2, max=100"`
    Password      *string            `json:"password" validate:"required, min=6"`
    Email         *string            `json:"email" validate:"email, required"` //validate email means it should have an @
    Phone         *string            `json:"phone" validate:"required"`
    Token         *string            `json:"token"`
    User_type     *string            `json:"user_type" validate:"required, eq=ADMIN|eq=USER"`
    Refresh_token *string            `json:"refresh_token"`
    Created_at    time.Time          `json:"created_at"`
    Updated_at    time.Time          `json:"updated_at"`
    User_id       string             `json:"user_id"`
}

还要确保下载“mongo”包:

package database
import (
    "fmt"
    "log"
    "os"
    "time"
    "context"
    "github.com/joho/godotenv"
    "go.mongodb.org/mongo-driver/mongo"
    "go/mongodb.org/mongo-driver/mongo/options"
)
func DBinstance() *mongo.Client{
    err := godotenv.Load(".env")
    if err != nil {
        log.Fatal("Error locading the .env file")
    }
    MongoDb := os.Getenv("THE_MONGODB_URL")
    client, err := mongo.NewClient(options.Client().ApplyURI(MongoDb))
    if err != nil {
        log.Fatal(err)
    }
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    err = client.Connect(ctx)
    if err!=nil{
        log.Fatal(err)
    }
    fmt.Println("Connected to MongoDB!!")
    return client
}
var Client *mongo.Client = DBinstance()
func OpenCollection(client *mongo.Client, collectionName string) *mongo.Collection {
    var collection *mongo.Collection = client.Database("cluster0").Collection(collectionName)
    return collection
}

这里我们将您的 mongo 数据库与应用程序连接。

我们使用“godotenv”加载环境变量,我们将在主目录的 .env 文件中设置这些变量。
DBinstance 函数,我们从 .env 文件中获取“THE_MONGODB_URL”的值(我们将在接下来的步骤中创建该值)并使用该值创建一个新的 mongoDB 客户端。
'context' 用于设置 10 秒的超时时间。
OpenCollection Function() 将 client 和 collectionName 作为输入并为其创建一个集合。

第 6 步。 对于路由,我们将创建两个不同的文件:authRouter 和 userRouter。 authRouter 包括 '/signup' 和 '/login' 。这些将向所有人公开,以便他们可以授权自己。 userRouter 不会向所有人公开。它将包括“/users”和“/users/:user_id”。

创建一个名为routes的文件夹并向其中添加两个文件:

  • userRouter.go
  • authRouter.go

在 userRouter.go 中输入以下代码:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ 
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

步骤 7. 在 authRouter.go 中输入以下代码:

go mod init github.com/1shubham7/jwt

步骤8.创建一个名为controllers的文件夹并向其中添加一个名为“userController.go”的文件。在其中输入以下代码。

package main
import(
    "github.com/gin-gonic/gin"
    "os"
    routes "github.com/1shubham7/jwt/routes"
    "github.com/joho/godotenv"
    "log"
)
func main() {
    err := godotenv.Load(".env")
    if err != nil {
        log.Fatal("Error locading the .env file")
    }
    port := os.Getenv("PORT")
    if port == "" {
        port = "1111"
    }
    router := gin.New()
    router.Use(gin.Logger())
    routes.AuthRoutes(router)
    routes.UserRoutes(router)
    // creating two APIs
    router.GET("/api-1", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-1"})
    })
    router.GET("api-2", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-2"})
    })
    router.Run(":" + port)
}

这两个变量已经在我们之前的代码中使用过。

第 10 步。 让我们首先创建 GetUserById() 函数。在 GetUserById() 函数中输入以下代码:

go get github.com/gin-gonic/gin

第 11 步。 让我们创建一个名为 helpers 的文件夹,并在其中添加一个名为 authHelper.go 的文件。在 authHelper.go 中输入以下代码:

package models
import (
    "go.mongodb.org/mongo-driver/bson/primitive"
    "time"
)
type User struct {
    ID            primitive.ObjectID `bson:"id"`
    First_name    *string            `json:"first_name" validate:"required, min=2, max=100"`
    Last_name     *string            `json:"last_name" validate:"required, min=2, max=100"`
    Password      *string            `json:"password" validate:"required, min=6"`
    Email         *string            `json:"email" validate:"email, required"` //validate email means it should have an @
    Phone         *string            `json:"phone" validate:"required"`
    Token         *string            `json:"token"`
    User_type     *string            `json:"user_type" validate:"required, eq=ADMIN|eq=USER"`
    Refresh_token *string            `json:"refresh_token"`
    Created_at    time.Time          `json:"created_at"`
    Updated_at    time.Time          `json:"updated_at"`
    User_id       string             `json:"user_id"`
}

MatchUserTypeToUserId() 函数仅匹配用户是管理员还是用户。
我们在 MatchUserTypeToUserId() 中使用 CheckUserType() 函数,这只是检查一切是否正常(如果我们从 user 获得的 user_type 与 userType 变量相同。

第 12 步。 我们现在可以处理 userController.go 的 SignUp() 函数:

package database
import (
    "fmt"
    "log"
    "os"
    "time"
    "context"
    "github.com/joho/godotenv"
    "go.mongodb.org/mongo-driver/mongo"
    "go/mongodb.org/mongo-driver/mongo/options"
)
func DBinstance() *mongo.Client{
    err := godotenv.Load(".env")
    if err != nil {
        log.Fatal("Error locading the .env file")
    }
    MongoDb := os.Getenv("THE_MONGODB_URL")
    client, err := mongo.NewClient(options.Client().ApplyURI(MongoDb))
    if err != nil {
        log.Fatal(err)
    }
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    err = client.Connect(ctx)
    if err!=nil{
        log.Fatal(err)
    }
    fmt.Println("Connected to MongoDB!!")
    return client
}
var Client *mongo.Client = DBinstance()
func OpenCollection(client *mongo.Client, collectionName string) *mongo.Collection {
    var collection *mongo.Collection = client.Database("cluster0").Collection(collectionName)
    return collection
}
  • 我们创建了一个 User 类型的变量用户。

  • validationErr 用于验证结构体标签,我们已经讨论过这一点。

  • 我们还使用计数变量来验证。就像如果我们已经找到包含用户电子邮件的文档,那么计数将大于 0,然后我们可以处理该错误(错误)

  • 然后我们使用 'time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))' 来设置 Created_at、Updated_at 结构体字段的时间。当用户尝试注册时,函数 SignUp() 将运行,并且该特定时间将存储在 Created_at、Updated_at 结构体字段中。

  • 然后我们使用GenerateAllTokens()函数创建令牌,我们将在下一步中在同一包的tokenHelper.go文件中创建令牌。

  • 我们还有一个 HashPassword() 函数,它除了对 user.password 进行哈希处理并用哈希后的密码替换 user.password 之外什么也不做。我们稍后也会创建那个东西。

  • 然后我们只需将数据和令牌等插入到 userCollection

  • 如果一切顺利,我们将返回 StatusOK。

步骤 13. 在 helpers 文件夹中创建一个名为“tokenHelper.go”的文件,并在其中输入以下代码。

go get go.mongodb.org/mongo-driver/mongo

还要确保下载 github.com/dgrijalva/jwt-go 包:

package routes
import (
    "github.com/gin-gonic/gin"
    controllers "github.com/1shubham7/jwt/controllers"
    middleware "github.com/1shubham7/jwt/middleware"
)
// user should not be able to use userRoute without the token
func UserRoutes (incomingRoutes *gin.Engine) {
    incomingRoutes.Use(middleware.Authenticate())
    // user routes are public routes but these must be authenticated, that
    // is why we have Authenticate() before these
    incomingRoutes.GET("/users", controllers.GetUsers())
    incomingRoutes.GET("users/:user_id", controllers.GetUserById())
}
  • 这里我们使用 github.com/dgrijalva/jwt-go 来生成令牌。

  • 我们正在创建一个名为 SignedDetails 的结构,其中包含生成令牌所需的字段名称。

  • 我们正在使用 NewWithClaims 生成新令牌,并将值赋予 Claims 和 refreshClaims 结构。 Claims 在用户首次使用时拥有令牌,refreshClaims 在用户必须刷新令牌时拥有令牌。也就是说,他们之前有一个令牌,但现在已过期。

  • time.Now().Local().Add(time.Hour *time.Duration(120)).Unix() 用于设置令牌的到期时间。

  • 然后我们只返回三个东西 - token、refreshToken 和 err,我们在 SignUp() 函数中使用它们。

步骤 14. 在与 SignUp() 函数相同的文件中,让我们创建我们在步骤 9 中讨论过的 HashPassword() 函数。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ 
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
  • 我们只是使用 bcrypt 包中的GenerateFromPassword()方法,该方法用于根据实际密码生成哈希密码。

  • 这很重要,因为我们不希望黑客侵入我们的系统并窃取所有密码,这也是为了用户的隐私。

  • []byte(字节数组)只是字符串。

第 15 步。 让我们在 'userController.go' 中创建 Login() 函数,在后面的步骤中我们可以创建 Login() 使用的函数:

go mod init github.com/1shubham7/jwt
  • 我们正在创建两个 User 类型的变量,它们是 user 和 Founduser。并将请求中的数据提供给用户。

  • 在 'userCollection.FindOne(ctx, bson.M{"email": user.Email}).Decode(&foundUser)' 的帮助下,我们通过他/她的电子邮件查找用户,如果找到,将其存储在foundUser变量中。

  • 然后我们使用VerifyPassword()函数来验证密码并存储它,记住我们在VerifyPassword()中将指针作为参数,如果没有,它将创建参数中的新实例而不是参数实际上改变了它们。

  • 我们将在下一步中创建VerifyPassword()。

  • 然后我们简单地使用GenerateAllTokens()和UpdateAllTokens()来生成和更新令牌和refreshToken(它们基本上是令牌)。

  • 每一步,我们都在处理错误。

第 16 步。 让我们在与 Login() 函数相同的文件中创建VerifyPassword() 函数:

package main
import(
    "github.com/gin-gonic/gin"
    "os"
    routes "github.com/1shubham7/jwt/routes"
    "github.com/joho/godotenv"
    "log"
)
func main() {
    err := godotenv.Load(".env")
    if err != nil {
        log.Fatal("Error locading the .env file")
    }
    port := os.Getenv("PORT")
    if port == "" {
        port = "1111"
    }
    router := gin.New()
    router.Use(gin.Logger())
    routes.AuthRoutes(router)
    routes.UserRoutes(router)
    // creating two APIs
    router.GET("/api-1", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-1"})
    })
    router.GET("api-2", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-2"})
    })
    router.Run(":" + port)
}
  • 我们只是使用 bcrypt 包中的 CompareHashAndPassword() 方法,该方法用于比较哈希密码。并根据结果返回一个布尔值。

  • []byte(字节数组)只是字符串,但 []byte 有助于比较。

第 17 步。 让我们在“tokenHelper.go”文件中创建 UpdateAllTokens() 函数:

go get github.com/gin-gonic/gin
  • 我们正在创建一个名为 updateObj 的变量,其类型为 Primitive.D。 MongoDB 的 Go 驱动程序中的 Primitive.D 类型是 BSON 文档的表示。

  • Append() 每次运行时都会向 updateObj 追加一个键值对。

  • 然后使用 'time.Parse(time.RFC3339, time.Now().Format(time.RFC3339))' 将当前时间(更新发生且函数运行的时间)更新为 Updated_at .

  • 代码块的其余部分正在使用 mongoDB 集合的 UpdateOne 方法执行更新。

  • 最后一步我们也会处理错误,以防出现任何错误。

第 18 步。 在继续之前,让我们下载 go.mongodb.org/mongo-driver 包:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ 
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

第 19 步。 现在让我们研究 GetUserById() 函数。请记住,GetUserById() 是供用户访问自己的信息的,管理员可以访问所有用户数据,用户只能访问他们自己的数据。

go mod init github.com/1shubham7/jwt
  • 从请求中获取 user_id 并将其存储在 userId 变量中。

  • 创建一个名为 user 的变量,其类型为 User。然后只需在 user_id 的帮助下在我们的数据库中搜索用户,如果 user_id 匹配,我们将将该人的信息存储在 user 变量中。

  • 如果一切顺利,StatusOk

  • 我们也在处理每一步的错误。

第 20 步。 现在让我们研究 GetUsers() 函数。请记住,只有管理员可以访问 GetUsers() 函数,因为它将包含所有用户的数据。在与 GetUserById()、Login() 和 SignUp() 函数相同的文件中创建 GetUsers() 函数:

package main
import(
    "github.com/gin-gonic/gin"
    "os"
    routes "github.com/1shubham7/jwt/routes"
    "github.com/joho/godotenv"
    "log"
)
func main() {
    err := godotenv.Load(".env")
    if err != nil {
        log.Fatal("Error locading the .env file")
    }
    port := os.Getenv("PORT")
    if port == "" {
        port = "1111"
    }
    router := gin.New()
    router.Use(gin.Logger())
    routes.AuthRoutes(router)
    routes.UserRoutes(router)
    // creating two APIs
    router.GET("/api-1", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-1"})
    })
    router.GET("api-2", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-2"})
    })
    router.Run(":" + port)
}
  • 首先,我们将检查请求是否来自管理员,我们借助之前步骤中创建的 CheckUserType() 来完成此操作。

  • 然后我们正在设置您想要每页的记录数。

  • 我们可以通过从请求中获取 recodePerPage 并将其转换为 int 来做到这一点,这是由 srtconv 完成的。

  • 如果recordPerPage设置错误或者recordPerPage小于1,默认每页有9条记录

  • 同样,我们在变量“page”中获取页码。

  • 默认情况下,我们的页码为 1 和 9 recordPerPage。

  • 然后我们创建了三个阶段(matchStage、groupStage、projectStage)。

  • 然后我们使用 Aggregate() 函数在 Mongo 管道中设置这三个阶段

  • 此外,我们每一步都会处理错误。

第 21 步。 我们的 'userController.go' 现已准备就绪,这是完成后 'userController.go' 文件的样子:

go get github.com/gin-gonic/gin

第 22 步。 现在我们可以处理身份验证部分了。为此,我们将创建一个身份验证中间件。创建一个名为“middleware”的文件夹,并在其中创建一个名为“authMiddleware.go”的文件。在文件中输入以下代码:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ 
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

步骤 23. 现在让我们创建 ValidateToken() 函数,我们将在 'tokenHelper.go' 中创建此函数:

go mod init github.com/1shubham7/jwt
  • ValidateToken 接受signedToken 并返回该Token 的SignedDetails 以及错误消息。 "" 如果没有错误的话。

  • ParseWithClaims() 函数用于获取令牌并将其存储在名为 token 的变量中。

  • 然后我们使用令牌上的 Claims 方法检查令牌是否正确。我们将结果存储在声明变量中。

  • 然后我们使用 ExpiresAt() 函数检查令牌是否已过期,如果当前时间大于 ExpiresAt 时间,则令牌已过期。

  • 然后简单地返回声明变量以及消息。

第 24 步。 现在我们已经基本完成了,让我们执行“go mod tidy”,此命令会检查您的 go.mod 文件,它会删除我们安装但未使用的所有包/依赖项并下载我们正在使用但尚未下载的所有依赖项。

package main
import(
    "github.com/gin-gonic/gin"
    "os"
    routes "github.com/1shubham7/jwt/routes"
    "github.com/joho/godotenv"
    "log"
)
func main() {
    err := godotenv.Load(".env")
    if err != nil {
        log.Fatal("Error locading the .env file")
    }
    port := os.Getenv("PORT")
    if port == "" {
        port = "1111"
    }
    router := gin.New()
    router.Use(gin.Logger())
    routes.AuthRoutes(router)
    routes.UserRoutes(router)
    // creating two APIs
    router.GET("/api-1", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-1"})
    })
    router.GET("api-2", func(c *gin.Context){
        c.JSON(200, gin.H{"success":"Access granted for api-2"})
    })
    router.Run(":" + port)
}

Step-by-Step Guide to Implementing JWT Authentication in Go (Golang)

输出

我们的 JWT 身份验证项目已准备就绪,要最终运行应用程序,请在终端中输入以下命令:

go get github.com/gin-gonic/gin

您将得到类似的输出:

Step-by-Step Guide to Implementing JWT Authentication in Go (Golang)

这将使服务器启动并运行,您可以使用curl或Postman API来发送请求和接收响应。或者您可以简单地将此 API 与前端框架集成。至此,我们的身份验证 API 已准备就绪,放心吧!

结论

在本文中,我们讨论了创建 JWT 身份验证的最快方法之一,我们在项目中使用了 Gin-Gonic 框架。这不是您的“只是另一个身份验证 API”。 Gin 比 NodeJS 快 300%,这使得这个身份验证 API 非常快速和高效。我们使用的项目结构也是行业级的项目结构。您可以进行进一步的更改,例如将 SECRET_KEY 存储在 .env 文件中等等,以使此 API 变得更好。您还可以在这里找到该项目的源代码 - 1Shubham7/go-jwt-token.

确保遵循所有步骤来创建项目并添加更多功能,并使用代码来更好地理解它。学习身份验证的最佳方法是创建自己的项目。

以上是在 Go (Golang) 中实现 JWT 身份验证的分步指南的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn