英文:
Issues with gorilla/csrf
问题
我无法理解如何在不直接注入字段的情况下让gorilla的csrf工作。它一直在谈论通过头部和Cookie传递,但是我所做的一切似乎都不起作用...这是我在Go服务器上的代码:
package main
import (
"gorilla/mux"
"gorilla/csrf"
"net/http"
"log"
"encoding/json"
"http/template"
"time"
)
func showLoginPage(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Set-Cookie", "_gorilla_csrf="+csrf.Token(r))
templates.ExecuteTemplate(w, "<template_here>", nil)
}
func doLogin(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Set-Cookie", "_gorilla_csrf="+csrf.Token(r))
/**
builds resp
**/
w.Write(resp)
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/login", showLoginPage).Methods("GET")
r.HandleFunc("/login", doLogin).Methods("POST")
r.PathPrefix("/js/").Handler(http.StripPrefix("/js/", http.FileServer(http.Dir("./js"))))
r.PathPrefix("/css/").Handler(http.StripPrefix("/css/", http.FileServer(http.Dir("./css"))))
srv := &http.Server{
Handler: csrf.Protect([]byte("very-secret-string"), csrf.Secure(false))(r),
Addr: "127.0.0.1:8000",
// Good practice: enforce timeouts for servers you create!
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
}
而在我的前端代码中,我使用以下代码来更新所有请求:
var getCookie = function(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1);
if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
}
return "";
};
$.ajaxPrefilter(function( options ) {
options.beforeSend = function (xhr) {
xhr.setRequestHeader('X-CSRF-Token', getCookie('_gorilla_csrf'));
}
});
我知道我肯定漏掉了什么,但我真的无法理解。非常感谢任何帮助。
英文:
So, for the life of me I cannot figure out how to get gorilla's csrf to work when not injecting it straight into fields. It keeps talking about passing it through headers and cookies, but nothing I do seems to work... here's what I have for my go server:
`
package main
import (
"gorilla/mux"
"gorilla/csrf"
"net/http"
"log"
"encoding/json"
"http/template"
"time"
)
func showLoginPage(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Set-Cookie", "_gorilla_csrf="+csrf.Token(r))
templates.ExecuteTemplate(w, "<template_here>", nil)
}
func doLogin(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Set-Cookie", "_gorilla_csrf="+csrf.Token(r))
/**
builds resp
**/
w.Write(resp)
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/login", showLoginPage).Methods("GET")
r.HandleFunc("/login", doLogin).Methods("POST")
r.PathPrefix("/js/").Handler(http.StripPrefix("/js/", http.FileServer(http.Dir("./js"))))
r.PathPrefix("/css/").Handler(http.StripPrefix("/css/", http.FileServer(http.Dir("./css"))))
srv := &http.Server{
Handler: csrf.Protect([]byte("very-secret-string"), csrf.Secure(false))(r),
Addr: "127.0.0.1:8000",
// Good practice: enforce timeouts for servers you create!
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
}
`
whereas, on my frontend I have this so that all requests get updated:
`
var getCookie = function(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1);
if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
}
return "";
};
$.ajaxPrefilter(function( options ) {
options.beforeSend = function (xhr) {
xhr.setRequestHeader('X-CSRF-Token', getCookie('_gorilla_csrf'));
}
});
`
I know I have to be missing something, but I really just can't seem to grasp this at all. Any help would be very appreciated.
答案1
得分: 1
看起来你正在使用这行代码覆盖了由Gorilla创建的真实CSRF令牌。Gorilla使用会话存储来保存用于验证的真实CSRF令牌。
w.Header().Set("Set-Cookie", "_gorilla_csrf="+csrf.Token(r))
请不要触碰_gorilla_csrf
这个cookie。
Gorilla只支持通过form field
和header
进行CSRF防护。所以选择其中一种方式,他们的readme中包含了你所需的必要信息(表单字段、头部和自定义字段名和头部名)。
gorilla/csrf
按照以下顺序检查CSRF令牌:
gorilla/csrf首先检查HTTP头部,然后检查表单体,在后续的POST/PUT/PATCH/DELETE等请求中寻找令牌。
英文:
It seems you're overwriting the gorilla created real CSRF token using this line. Gorilla is using session store to keep real CSRF tokens for validation.
w.Header().Set("Set-Cookie", "_gorilla_csrf="+csrf.Token(r))
Please do not touch _gorilla_csrf
this cookie.
Gorilla supports the CSRF via form field
and header
only. So pick your choice, their readme has required information you need (Form field, Header and Customizing field name & header name).
gorilla/csrf
checks CSRF token in this order:
> gorilla/csrf inspects the HTTP headers (first) and form body (second) on subsequent POST/PUT/PATCH/DELETE/etc. requests for the token.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论