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

时间:2018-04-20 04:00:01

标签: go jwt

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

Router.go

a\\s

Controller.Login.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},

以上代码将为用户生成令牌,然后我将如何制作一个中间件,将邮递员头中的每个给定令牌与数据库保存令牌进行比较

  

如果授权用户将会访问,那么它将访问上述API。 如果它不是授权用户,则它将无法访问上述API并提供错误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) } }

我不明白我应该为此写些什么。我用Google搜索了很多次,找到像this这样的东西,但是我不太容易理解代码。任何人都可以告诉我如何保护API。先感谢您。

1 个答案:

答案 0 :(得分:1)

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

  

它使用jwt-go提供jwt认证中间件。它提供了额外的处理函数来提供将生成令牌的登录api以及可用于刷新令牌的附加刷新处理程序。

来自gin-jwt README.md的示例:

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)
}