Gin框架与《Web Development with Go》实践(四)

认证

应用中“认证”的工作流:

  1. 通过发送http请求到资源“/users/register”以使用户注册进系统
  2. 通过发送http请求到资源“/users/login”以使已注册用户登录到系统。服务器证实登录证书并产生一个JWT作为访问令牌。此令牌可以访问受保护的RESTful API服务器的资源。
  3. 用户可以使用JWT访问受保护的RESTful API服务器的资源。在"授权"的HTTP头部中,用户必须发送这个JWT作为“bearer token”。

产生和核实JWT

产生JWT

补充JWT知识;了解jwt-go的用法。

生成JWT的函数:
src/taskmanager2/common2/auth.go

// GenerateJWT generates a new JWT token
func GenerateJWT(name, role string) (string, error) {
    // Create the Claims
    claims := AppClaims{
        name,
        role,
        jwt.StandardClaims{
            ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
            Issuer:    "admin",
        },
    }
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

    ss, err := token.SignedString(signKey)
    if err != nil {
        return "", err
    }

    return ss, nil
}

发送JWT给服务器

在postman中,使用如下格式:
"Authorization": "Bearer token_string”,

例如:
"Authorization":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ"
可以把JWT发送给服务器。

授权JWT

用于验证JWT的中间件

// Authorize Middleware for validating JWT tokens
func Authorize() gin.HandlerFunc {
    return func(c *gin.Context) {
        // Get token from request
        token, err := request.ParseFromRequestWithClaims(c.Request, request.OAuth2Extractor, &AppClaims{}, func(token *jwt.Token) (interface{}, error) {
            return verifyKey, nil
        })

        if err != nil {
            switch err.(type) {
            case *jwt.ValidationError: // JWT validation error
                vErr := err.(*jwt.ValidationError)

                switch vErr.Errors {
                case jwt.ValidationErrorExpired: //JWT expired
                    DisplayAppError(
                        c,
                        err,
                        "Access Token is expired, get a new Token",
                        401,
                    )
                default:
                    DisplayAppError(
                        c,
                        err,
                        "Error while parsing the Access Token!",
                        500,
                    )
                }
            default:
                DisplayAppError(
                    c,
                    err,
                    "Error while parsing Access Token!",
                    500)
            }
            c.Abort()
        }
        if token.Valid {
            c.Set("user", token.Claims.(*AppClaims).UserName)
            c.Next()
        } else {
            DisplayAppError(
                c,
                err,
                "Invalid Access Token",
                401,
            )
            c.Abort()
        }
    }
}

以资源“task”为例,在路径中使用router.Use()来添加授权中间件。
src/taskmanager2/routers2/task.go

package routers2

import (
    "gopkg.in/gin-gonic/gin.v1"
    "taskmanager2/controllers2"
    "taskmanager2/common2"
)

// SetTaskRoutes configures routes for task entity
func SetTaskRoutes(router *gin.Engine) *gin.Engine {

    taR := router.Group("/tm2/tasks")
    taR.Use(common2.Authorize())
    {
        taR.POST("", controllers2.CreateTask)
        taR.PUT(":id", controllers2.UpdateTask)
        taR.DELETE(":id", controllers2.DeleteTask)
        taR.GET("", controllers2.GetTasks)
        taR.GET("t/:id/", controllers2.GetTaskByID)
        taR.GET("users/:email/", controllers2.GetTasksByUser)
    }

    return router
}

你可能感兴趣的:(Gin框架与《Web Development with Go》实践(四))