JWT

  • JWT 使用 HS256 算法认证。
  • JWT 从 Authorization 请求头取出数据。

服务端(使用 map)

server.go

package main

import (
    "net/http"
    "time"

    jwt "github.com/dgrijalva/jwt-go"
    "github.com/labstack/echo"
    "github.com/labstack/echo/middleware"
)

func login(c echo.Context) error {
    username := c.FormValue("username")
    password := c.FormValue("password")

    if username == "jon" && password == "shhh!" {
        // Create token
        token := jwt.New(jwt.SigningMethodHS256)

        // Set claims
        claims := token.Claims.(jwt.MapClaims)
        claims["name"] = "Jon Snow"
        claims["admin"] = true
        claims["exp"] = time.Now().Add(time.Hour * 72).Unix()

        // Generate encoded token and send it as response.
        t, err := token.SignedString([]byte("secret"))
        if err != nil {
            return err
        }
        return c.JSON(http.StatusOK, map[string]string{
            "token": t,
        })
    }

    return echo.ErrUnauthorized
}

func accessible(c echo.Context) error {
    return c.String(http.StatusOK, "Accessible")
}

func restricted(c echo.Context) error {
    user := c.Get("user").(*jwt.Token)
    claims := user.Claims.(jwt.MapClaims)
    name := claims["name"].(string)
    return c.String(http.StatusOK, "Welcome "+name+"!")
}

func main() {
    e := echo.New()

    // Middleware
    e.Use(middleware.Logger())
    e.Use(middleware.Recover())

    // Login route
    e.POST("/login", login)

    // Unauthenticated route
    e.GET("/", accessible)

    // Restricted group
    r := e.Group("/restricted")
    r.Use(middleware.JWT([]byte("secret")))
    r.GET("", restricted)

    e.Logger.Fatal(e.Start(":1323"))
}

服务端(使用结构体)

server.go

package main

import (
    "net/http"
    "time"

    jwt "github.com/dgrijalva/jwt-go"
    "github.com/labstack/echo"
    "github.com/labstack/echo/middleware"
)

// jwtCustomClaims are custom claims extending default ones.
type jwtCustomClaims struct {
    Name  string `json:"name"`
    Admin bool   `json:"admin"`
    jwt.StandardClaims
}

func login(c echo.Context) error {
    username := c.FormValue("username")
    password := c.FormValue("password")

    if username == "jon" && password == "shhh!" {

        // Set custom claims
        claims := &jwtCustomClaims{
            "Jon Snow",
            true,
            jwt.StandardClaims{
                ExpiresAt: time.Now().Add(time.Hour * 72).Unix(),
            },
        }

        // Create token with claims
        token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

        // Generate encoded token and send it as response.
        t, err := token.SignedString([]byte("secret"))
        if err != nil {
            return err
        }
        return c.JSON(http.StatusOK, echo.Map{
            "token": t,
        })
    }

    return echo.ErrUnauthorized
}

func accessible(c echo.Context) error {
    return c.String(http.StatusOK, "Accessible")
}

func restricted(c echo.Context) error {
    user := c.Get("user").(*jwt.Token)
    claims := user.Claims.(*jwtCustomClaims)
    name := claims.Name
    return c.String(http.StatusOK, "Welcome "+name+"!")
}

func main() {
    e := echo.New()

    // Middleware
    e.Use(middleware.Logger())
    e.Use(middleware.Recover())

    // Login route
    e.POST("/login", login)

    // Unauthenticated route
    e.GET("/", accessible)

    // Restricted group
    r := e.Group("/restricted")

    // Configure middleware with the custom claims type
    config := middleware.JWTConfig{
        Claims:     &jwtCustomClaims{},
        SigningKey: []byte("secret"),
    }
    r.Use(middleware.JWTWithConfig(config))
    r.GET("", restricted)

    e.Logger.Fatal(e.Start(":1323"))
}

客户端

curl

登录

使用账号和密码登录获取 token。

curl -X POST -d 'username=jon' -d 'password=shhh!' localhost:1323/login

返回

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NjE5NTcxMzZ9.RB3arc4-OyzASAaUhC2W3ReWaXAt_z2Fd3BN4aWTgEY"
}

请求

Authorization 请求头设置 token,发送请求获取资源。

curl localhost:1323/restricted -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NjE5NTcxMzZ9.RB3arc4-OyzASAaUhC2W3ReWaXAt_z2Fd3BN4aWTgEY"

返回

Welcome Jon Snow!
文档更新时间: 2020-07-20 16:53   作者:kuteng