我可以将 JWT 令牌放在 Golang Echo 框架的上下文中吗?

Posted

技术标签:

【中文标题】我可以将 JWT 令牌放在 Golang Echo 框架的上下文中吗?【英文标题】:Can I put JWT token in Context in Golang Echo framework? 【发布时间】:2021-02-17 10:15:03 【问题描述】:

我正在学习如何使用带有 Golang 的 Echo 框架实现有用且强大的 Web 服务器。

现在我正在尝试构建一个附加 JWT 令牌和哈希函数的真实用户身份验证。 在 Echo 官方文档和几篇博客文章中,我进行了身份验证过程,将 jwt 令牌放入 cookie 并在进入路由受限时取出。

但是,据说将身份验证方法保存在cookie,本地存储和会话存储中是非常危险的,因为我不认识的人可以访问这三种方法,并侵入我的秘密信息。

然后我尝试将令牌保存在 echo Context 中,而不是 cookie。

我编写了将令牌放入上下文的代码,但我不知道如何从上下文中获取它们,并提交到身份验证过程。

也许 jwt 配置中的 TokenLookup 属性决定了我可以在哪里存储令牌,例如标头、cookie、查询和参数。那么我可以在回显上下文中存储 JWT 令牌吗?

我附上了我的示例代码。

package main

import (
    "fmt"
    "net/http"
    "time"

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

    // Throws unauthorized error
    if username != "jon" || password != "shhh!" 
        return echo.ErrUnauthorized
    

    // Set custom claims
    claims := &jwtCustomClaims
        "Jon Snow",
        true,
        jwt.StandardClaims
            ExpiresAt: time.Now().Add(time.Hour * 3).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
    

    c.Set("Authorization", fmt.Sprintf("Bearer %s", t))
    return c.Redirect(http.StatusPermanentRedirect, "/restricted")


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.GET("/login", func(c echo.Context) error 
        return c.html(http.StatusOK,
            `
                <html>
                    <head>
                        <meta charset="utf-8" />
                        <title>Login Page</title>
                    </head>
                    <body>
                        <form action="/login" method="post">
                            <input type="text" name="username" />
                            <input type="text" name="password" />
                            <button type="submit">Action</button>
                        </form>
                    </body>
                </html>
            `,
        )
    )
    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"),
        TokenLookup: "cookie:FakeToken",
    
    r.Use(middleware.JWTWithConfig(config))
    r.GET("", restricted)

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

在上下文中保存令牌在函数 login 中执行。

【问题讨论】:

【参考方案1】:

阅读https://echo.labstack.com/guide/context,

echo.Context 表示当前 HTTP 请求的上下文。它保存请求和响应引用、路径、路径参数、数据、注册的处理程序和用于读取请求和写入响应的 API。由于 Context 是一个接口,因此很容易使用自定义 API 对其进行扩展。

这不能替代凭据的客户端存储。毕竟客户端是需要认证的。

【讨论】:

以上是关于我可以将 JWT 令牌放在 Golang Echo 框架的上下文中吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查JWT令牌剩余有效时间golang

我在哪里可以将 jwt 令牌存储在 localStorage 中?

Angular2-jwt - AuthHttp,刷新令牌,把它们放在一起

在 Angular / Golang 项目中使用 JWT

注销后 JWT 的使用

检查黑名单中的 JWT 令牌