Categories: GoFrame 教程

GoFrame 高级特性-CSRF防御设置

跨站请求伪造(英语:​Cross-Site Request Forgery​),也被称为 ​one-click attack​ 或者 ​session riding​,通常缩写为 ​CSRF ​或者 ​XSRF​, 是一种挟制用户在当前已登录的​Web​应用程序上执行非本意的操作的攻击方法。跟跨网站脚本(​XSS​)相比,​XSS​利用的是用户对指定网站的信任,​CSRF ​利用的是网站对用户网页浏览器的信任。

如何防御

这里我们选择通过​token​的方式对请求进行校验,通过中间件的方式实现,​CSRF​跨站点防御插件由社区包提供。

开发者可以通过对接口添加中间件的方式,增加​token​校验功能。

感兴趣的朋友可以阅读插件源码 https://github.com/gogf/csrf

使用方式

引入插件包

import "github.com/gogf/csrf"

配置接口中间件

csrf​插件支持自定义​csrf.Config​配置,​Config​中的​Cookie.Name​是中间件设置到请求返回​Cookie​中​token​的名称,​ExpireTime​是​token​超时时间,​TokenLength​是​token​长度,​TokenRequestKey​是后续请求需求带上的参数名。

s := g.Server()
s.Group("/api.v2", func(group *ghttp.RouterGroup) {
 group.Middleware(csrf.NewWithCfg(csrf.Config{
  Cookie: &http.Cookie{
   Name: "_csrf",// token name in cookie
  },
  ExpireTime:      time.Hour * 24,
  TokenLength:     32,
  TokenRequestKey: "X-Token",// use this key to read token in request param
 }))
 group.ALL("/csrf", func(r *ghttp.Request) {
  r.Response.Writeln(r.Method + ": " + r.RequestURI)
 })
})

前端对接

通过配置后,前端在​POST​请求前从​Cookie​中读取​_csrf​的值(即​token​),然后请求发出时将​token​以​X-Token​(​TokenRequestKey​所设置)参数名置入请求中(可以是​Header​或者​Form​)即可通过​token​校验。

代码示例

使用默认配置

package main

import (
 "net/http"
 "time"

 "github.com/gogf/csrf"
 "github.com/gogf/gf/v2/frame/g"
 "github.com/gogf/gf/v2/net/ghttp"
)

// default cfg
func main() {
 s := g.Server()
 s.Group("/api.v2", func(group *ghttp.RouterGroup) {
  group.Middleware(csrf.New())
  group.ALL("/csrf", func(r *ghttp.Request) {
   r.Response.Writeln(r.Method + ": " + r.RequestURI)
  })
 })
 s.SetPort(8199)
 s.Run()
}

使用自定义配置

package main

import (
 "net/http"
 "time"

 "github.com/gogf/csrf"
 "github.com/gogf/gf/v2/frame/g"
 "github.com/gogf/gf/v2/net/ghttp"
)

// set cfg
func main() {
 s := g.Server()
 s.Group("/api.v2", func(group *ghttp.RouterGroup) {
  group.Middleware(csrf.NewWithCfg(csrf.Config{
   Cookie: &http.Cookie{
    Name: "_csrf",// token name in cookie
    Secure:   true,
    SameSite: http.SameSiteNoneMode,// 自定义samesite    
   },
   ExpireTime:      time.Hour * 24,
   TokenLength:     32,
   TokenRequestKey: "X-Token",// use this key to read token in request param
  }))
  group.ALL("/csrf", func(r *ghttp.Request) {
   r.Response.Writeln(r.Method + ": " + r.RequestURI)
  })
 })
 s.SetPort(8199)
 s.Run()
}

terry

这个人很懒,什么都没有留下~

Share
Published by
terry

Recent Posts

聊聊vue3中的defineProps

在Vue 3中,defineP…

1 周 ago

在 Chrome 中删除、允许和管理 Cookie

您可以选择删除现有 Cooki…

2 周 ago

自定义指令:聊聊vue中的自定义指令应用法则

今天我们来聊聊vue中的自定义…

3 周 ago

聊聊Vue中@click.stop和@click.prevent

一起来学下聊聊Vue中@cli…

4 周 ago

Nginx 基本操作:启动、停止、重启命令。

我们来学习Nginx基础操作:…

1 月 ago

Vue3:手动清理keep-alive组件缓存的方法

Vue3中手动清理keep-a…

1 月 ago