go - 使用 gin 包在 golang 中实现 JWT 中间件并保护其他 API?

标签 go jwt

我想保护我的 API,以便授权用户可以访问我的 API。这里的路由器如下:-

Router.go

//here the customer will register.
Route{"SaveUser", "POST", "/signup", controller.SaveUser},
//here the customer will login with its username and password.
Route{"LoginUser", "POST", "/login", controller.Login},

//APIs that a valid user can access
Route{"SaveCustomers", "POST", "/customer", controller.SaveCustomers},
Route{"GetCustomers", "GET", "/customer", controller.GetCustomers},
Route{"GetCustomer", "GET", "/customer/:id", controller.GetCustomer},
Route{"UpdateCustomers", "PUT", "/customer/:id", controller.UpdateCustomers},

Controller.Login.go

package controller
import(
  // "encoding/json"
  "github.com/gin-gonic/gin"
  "go-training/Template1/config"
  "go-training/Template1/models"
  "fmt"
  "github.com/dgrijalva/jwt-go"
  "gopkg.in/mgo.v2/bson"
  "strings"
 )

 type User struct {
   Email string `json:"email"`
   Password  string    `json:"password"`
   jwt.StandardClaims
 }

 type user struct {
   email     string 
   password string 
 }
 func Login(c *gin.Context) {
  email := c.PostForm("email")
password := c.PostForm("password")
reqBody := new(user)
err := c.Bind(reqBody)
if err != nil {
    fmt.Println(err)
}
response := ResponseControllerList{}
conditions := bson.M{"email_id":email,"password":password}
data, err := models.GetAllUser(conditions)
dataCount, err := models.GetRecordsCount(config.SignupCollection, conditions)
counter:= 0
for _, signup := range data {
    if email == signup.EmailId && password == signup.Password {
        //fmt.Println("heloo")
        counter = 1
    }
}
if counter == 1 {
    fmt.Println("Match!")
    token := jwt.NewWithClaims(jwt.GetSigningMethod("HS256"), &User{
        Email: email,
        Password:  password,
    })
    fmt.Println(token)
    tokenstring, err := token.SignedString([]byte(""))
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(tokenstring)
 }

}

上面的代码将为用户生成 token 然后我将如何制作一个中间件来比较 postman header 中的每个给定 token 与数据库保存 token 和

If the authorized user will come then it will access the above mentioned APIs. If it is not a authorized user then it will not access the above APIs and gives the error of unauthorized user.

我不明白我应该为此写什么。我在谷歌上搜索了很多次,找到了类似 this 的东西但我不太容易理解代码。任何人都可以告诉我应该怎么做才能保护 API。先感谢您。

最佳答案

使用gin-jwt使用 JWT 保护 API 的包。

It uses jwt-go to provide a jwt authentication middleware. It provides additional handler functions to provide the login api that will generate the token and an additional refresh handler that can be used to refresh tokens.

示例来自 gin-jwt自述文件:

package main

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

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

func helloHandler(c *gin.Context) {
    claims := jwt.ExtractClaims(c)
    c.JSON(200, gin.H{
        "userID": claims["id"],
        "text":   "Hello World.",
    })
}

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

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

    // the jwt middleware
    authMiddleware := &jwt.GinJWTMiddleware{
        Realm:      "test zone",
        Key:        []byte("secret key"),
        Timeout:    time.Hour,
        MaxRefresh: time.Hour,
        Authenticator: func(userId string, password string, c *gin.Context) (string, bool) {
            if (userId == "admin" && password == "admin") || (userId == "test" && password == "test") {
                return userId, true
            }

            return userId, false
        },
        Authorizator: func(userId string, c *gin.Context) bool {
            if userId == "admin" {
                return true
            }

            return false
        },
        Unauthorized: func(c *gin.Context, code int, message string) {
            c.JSON(code, gin.H{
                "code":    code,
                "message": message,
            })
        },
        // TokenLookup is a string in the form of "<source>:<name>" that is used
        // to extract token from the request.
        // Optional. Default value "header:Authorization".
        // Possible values:
        // - "header:<name>"
        // - "query:<name>"
        // - "cookie:<name>"
        TokenLookup: "header:Authorization",
        // TokenLookup: "query:token",
        // TokenLookup: "cookie:token",

        // TokenHeadName is a string in the header. Default value is "Bearer"
        TokenHeadName: "Bearer",

        // TimeFunc provides the current time. You can override it to use another time value. This is useful for testing or if your server uses a different time zone than your tokens.
        TimeFunc: time.Now,
    }

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

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

    http.ListenAndServe(":"+port, r)
}

关于go - 使用 gin 包在 golang 中实现 JWT 中间件并保护其他 API?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49933783/

相关文章:

go - 理解 `interface{}` 在 Go 中的用法的问题

angular - SPA 中 token 存储和刷新的选项

jwt - 承载未通过身份验证 : Signature validation failed

firebase - 在将用户添加到 Firebase 时从 Go 管理后端获取消息 token ,在 Javascript 中注册时结束

http - TCP 是同一主机中 Go 程序之间通信的最佳方法吗?

go - 转到结构函数和*

performance - 如何在基准测试中击败Go优化器?

typescript - 如何使用 typescript 获取 `jsonwebtoken` 的 token 过期

firebase - 900个字符的Firebase Auth idToken大小正常吗?

c# - .NET Core 授权 - JWT Bearer 上的常量 403