gorilla/csrf存在的问题

huangapple go评论88阅读模式
英文:

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 (
	&quot;gorilla/mux&quot;
	&quot;gorilla/csrf&quot;
	&quot;net/http&quot;
	&quot;log&quot;
	&quot;encoding/json&quot;
	&quot;http/template&quot;
	&quot;time&quot;
)

func showLoginPage(w http.ResponseWriter, r *http.Request) {
	w.Header().Set(&quot;Set-Cookie&quot;, &quot;_gorilla_csrf=&quot;+csrf.Token(r))
	templates.ExecuteTemplate(w, &quot;&lt;template_here&gt;&quot;, nil)
}


func doLogin(w http.ResponseWriter, r *http.Request) {
	w.Header().Set(&quot;Set-Cookie&quot;, &quot;_gorilla_csrf=&quot;+csrf.Token(r))
	/**
	builds resp
	**/
	w.Write(resp)
}

func main() {
	r := mux.NewRouter()
	r.HandleFunc(&quot;/login&quot;, showLoginPage).Methods(&quot;GET&quot;)
	r.HandleFunc(&quot;/login&quot;, doLogin).Methods(&quot;POST&quot;)
	r.PathPrefix(&quot;/js/&quot;).Handler(http.StripPrefix(&quot;/js/&quot;, http.FileServer(http.Dir(&quot;./js&quot;))))
	r.PathPrefix(&quot;/css/&quot;).Handler(http.StripPrefix(&quot;/css/&quot;, http.FileServer(http.Dir(&quot;./css&quot;))))

	srv := &amp;http.Server{
		  Handler:      csrf.Protect([]byte(&quot;very-secret-string&quot;), csrf.Secure(false))(r),
		  Addr:         &quot;127.0.0.1:8000&quot;,
		  // 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 + &quot;=&quot;;
  var ca = document.cookie.split(&#39;;&#39;);
  for (var i = 0; i &lt; ca.length; i++) {
      var c = ca[i];
      while (c.charAt(0) == &#39; &#39;) c = c.substring(1);
      if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
  }
  return &quot;&quot;;
};
$.ajaxPrefilter(function( options ) {
    options.beforeSend = function (xhr) { 
        xhr.setRequestHeader(&#39;X-CSRF-Token&#39;, getCookie(&#39;_gorilla_csrf&#39;));
    }
});

`

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 fieldheader进行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(&quot;Set-Cookie&quot;, &quot;_gorilla_csrf=&quot;+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.

huangapple
  • 本文由 发表于 2017年6月13日 06:32:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/44509679.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定