GoFrame 高級特性-CSRF防御設置

2022-04-15 11:03 更新

跨站請求偽造(英語:?Cross-Site Request Forgery?),也被稱為 ?one-click attack? 或者 ?session riding?,通??s寫為 ?CSRF ?或者 ?XSRF?, 是一種挾制用戶在當前已登錄的?Web?應用程序上執(zhí)行非本意的操作的攻擊方法。跟跨網站腳本(?XSS?)相比,?XSS?利用的是用戶對指定網站的信任,?CSRF ?利用的是網站對用戶網頁瀏覽器的信任。

如何防御

這里我們選擇通過?token?的方式對請求進行校驗,通過中間件的方式實現(xiàn),?CSRF?跨站點防御插件由社區(qū)包提供。

開發(fā)者可以通過對接口添加中間件的方式,增加?token?校驗功能。

感興趣的朋友可以閱讀插件源碼 https://github.com/gogf/csrf

使用方式

引入插件包

import "github.com/gogf/csrf"

配置接口中間件

?csrf?插件支持自定義?csrf.Config?配置,?Config?中的?Cookie.Name?是中間件設置到請求返回?Cookie?中?token?的名稱,?ExpireTime?是?token?超時時間,?TokenLength?是?token?長度,?TokenRequestKey?是后續(xù)請求需求帶上的參數(shù)名。

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?),然后請求發(fā)出時將?token?以?X-Token?(?TokenRequestKey?所設置)參數(shù)名置入請求中(可以是?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()
}


以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號