Go语言 Echo框架CSRF确认不适用于表单提交

5f0d552i  于 2023-04-18  发布在  Go
关注(0)|答案(1)|浏览(113)

我正在尝试使用Go中的Echo框架为一个登录表单实现CSRF保护,我正在使用c.Validate方法来验证CSRF令牌,但即使返回的错误为nil时,代码仍然会触发“Invalid CSRF token”错误,我已经尝试过更改变量名和使用不同的令牌查找但错误仍然存在。我如何修复此问题并使用Echo成功验证登录表单中的CSRF令牌?
Go代码:

e := echo.New()
e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
  TokenLookup: "form:_csrf",
}))
e.GET("/sign-in", func(c echo.Context) error {
  return c.Render(http.StatusOK, "sign-in.html", map[string]interface{}{
    "csrf":  c.Get(middleware.DefaultCSRFConfig.ContextKey),
  })
}).Name = "signin"
e.POST("/login", func(c echo.Context) error {
  // Validate CSRF token
  csrfErr := c.Validate(middleware.DefaultCSRFConfig.TokenLookup + ":form:_csrf")
  if csrfErr != nil {
    return echo.NewHTTPError(http.StatusUnauthorized, "Invalid CSRF token")
  }

  // Rest of the code
}).Name = "login"

Html代码:

<form action="/login" method="post" autocomplete="off">
    <input type="hidden" name="_csrf" value="{{.csrf}}">
    <div class="mb-3">
        <label class="form-label">Email address</label>
        <input type="email" name="email" class="form-control" placeholder="your@email.com" autocomplete="off">
    </div>
    <div class="mb-2">
        <label class="form-label"> Password </label>
        <div class="input-group input-group-flat">
            <input type="password" name="password" class="form-control" placeholder="Your password" autocomplete="off">
        </div>
    </div>
    <div class="form-footer">
        <button type="submit" class="btn btn-primary w-100">Sign in</button>
    </div>
</form>

我已经尝试更改变量名,使用不同的令牌查找,并确保错误变量为nill,但错误仍然存在。

6jygbczu

6jygbczu1#

你不需要下面的线。删除它们就行了。

// Validate CSRF token
csrfErr := c.Validate(middleware.DefaultCSRFConfig.TokenLookup + ":form:_csrf")
if csrfErr != nil {
    return echo.NewHTTPError(http.StatusUnauthorized, "Invalid CSRF token")
}

以下代码注册CSRF中间件。作为中间件,它在执行处理程序之前验证请求。如果请求到达处理程序,则意味着CSRF令牌有效。如果有疑问,请查看实现。

e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
    TokenLookup: "form:_csrf",
}))

下面是Validate的文档:

// Validate validates provided `i`. It is usually called after `Context#Bind()`.
// Validator must be registered using `Echo#Validator`.
Validate(i interface{}) error

它不是用于验证CSRF令牌。相反,它用于验证数据绑定(参见Binding Request Data)。在您的情况下,错误是ErrValidatorNotRegistered,这意味着(data binding) validator not registered

相关问题