测试带有 CSRF 的 POST 方法。

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

Testing post method with csrf

问题

我正在尝试为我的 Revel 应用程序编写一个注册测试方法。请看以下代码:

package tests

import "github.com/revel/revel"
import "github.com/PuerkitoBio/goquery"
import "bytes"
import "net/url"

//import "net/http"

var csrf string

type AccountTest struct {
    revel.TestSuite
}

func (self *AccountTest) Before() {
    //println("Set up")
}

func (self *AccountTest) TestGetSignUp() {
    self.Get("/signup")
    site := bytes.NewBuffer(self.ResponseBody)
    doc, _ := goquery.NewDocumentFromReader(site)
    doc.Find("input").Each(func(i int, s *goquery.Selection) {
        name, exists := s.Attr("name")
        if name == "csrf_token" && exists {
            csrf, _ = s.Attr("value")
        }
    })
    self.AssertOk()
    self.AssertContains("Sign Up")
    self.AssertContentType("text/html; charset=utf-8")
}

func (self *AccountTest) TestPostSignUp() {
    self.PostForm("/signup", url.Values{
        "name":         {"cormier"},
        "email":        {"cormisample.com"},
        "emailConfirm": {"cormier@sample.com"},
        "password":     {"Test!1234"},
        "termof":       {"true"},
        "csrf_token":   {csrf},
    })
    self.AssertOk()
    self.AssertContentType("text/html; charset=utf-8")
}

func (self *AccountTest) After() {
    //println("Tear down")
}

测试未通过 TestPostSignUp 函数,似乎是因为请求被我实现的 csrf 中间件 revel-csrf 拒绝了。如上所示,我读取了 csrf 令牌并保存到变量 csrf 中。通过 PostForm 请求我传递了该变量,但是没有起作用。

我的问题是,如何进行一个带有 post 请求的测试,以通过 csrf 保护。

英文:

I am trying to write a test method for sign up on my revel application. Look at the following code

package tests

import "github.com/revel/revel"
import "github.com/PuerkitoBio/goquery"
import "bytes"
import "net/url"

//import "net/http"

var csrf string

type AccountTest struct {
	revel.TestSuite
}

func (self *AccountTest) Before() {
	//println("Set up")
}

func (self *AccountTest) TestGetSignUp() {
	self.Get("/signup")
	site := bytes.NewBuffer(self.ResponseBody)
	doc, _ := goquery.NewDocumentFromReader(site)
	doc.Find("input").Each(func(i int, s *goquery.Selection) {
		name, exists := s.Attr("name")
		if name == "csrf_token" && exists {
			csrf, _ = s.Attr("value")
		}
	})
	self.AssertOk()
	self.AssertContains("Sign Up")
	self.AssertContentType("text/html; charset=utf-8")
}

func (self *AccountTest) TestPostSignUp() {
	self.PostForm("/signup", url.Values{
		"name":         {"cormier"},
		"email":        {"cormisample.com"},
		"emailConfirm": {"cormier@sample.com"},
		"password":     {"Test!1234"},
		"termof":       {"true"},
		"csrf_token":   {csrf},
	})
	self.AssertOk()
	self.AssertContentType("text/html; charset=utf-8")
}

func (self *AccountTest) After() {
	//println("Tear down")
} 

The test does not pass by TestPostSignUp function, it seems like, that the request is rejected through csrf middleware that I implemented revel-csrf. As you can see above, I read csrf token and save into variable(csrf). By Postform request I passed the variable, but does not work.

My question is, how to make a test with post request that will pass csrf protection.

答案1

得分: 5

我按照以下方式解决了这个问题:

package tests

import "github.com/revel/revel"
import "github.com/PuerkitoBio/goquery"
import "bytes"
import "net/url"

//import "net/http"

var csrf string

type AccountTest struct {
    revel.TestSuite
}

func (self *AccountTest) Before() {

    self.Get("/signup")
    site := bytes.NewBuffer(self.ResponseBody)
    doc, _ := goquery.NewDocumentFromReader(site)
    doc.Find("input").Each(func(i int, s *goquery.Selection) {
        name, exists := s.Attr("name")
        if name == "csrf_token" && exists {
            csrf, _ = s.Attr("value")
        }
    })

}

func (self *AccountTest) TestSignUp() {

    self.PostForm("/signup", url.Values{
        "name":         {"cormier"},
        "email":        {"cormier@sample.com"},
        "emailConfirm": {"cormier@sample.com"},
        "password":     {"Test!1234"},
        "termof":       {"true"},
        "csrf_token":   {csrf},
    })
    self.AssertOk()
    self.AssertContentType("text/html; charset=utf-8")
}

func (self *AccountTest) After() {
}
英文:

I solve the problem following:

package tests

    import "github.com/revel/revel"
    import "github.com/PuerkitoBio/goquery"
    import "bytes"
    import "net/url"
    
    //import "net/http"
    
    var csrf string
    
    type AccountTest struct {
    	revel.TestSuite
    }
    
    func (self *AccountTest) Before() {
    
    	self.Get("/signup")
    	site := bytes.NewBuffer(self.ResponseBody)
    	doc, _ := goquery.NewDocumentFromReader(site)
    	doc.Find("input").Each(func(i int, s *goquery.Selection) {
    		name, exists := s.Attr("name")
    		if name == "csrf_token" && exists {
    			csrf, _ = s.Attr("value")
    		}
    	})
    
    }
    
    func (self *AccountTest) TestSignUp() {
    
    	self.PostForm("/signup", url.Values{
    		"name":         {"cormier"},
    		"email":        {"cormier@sample.com"},
    		"emailConfirm": {"cormier@sample.com"},
    		"password":     {"Test!1234"},
    		"termof":       {"true"},
    		"csrf_token":   {csrf},
    	})
    	self.AssertOk()
    	self.AssertContentType("text/html; charset=utf-8")
    }
    
    func (self *AccountTest) After() {
    }

huangapple
  • 本文由 发表于 2014年9月25日 18:04:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/26035816.html
匿名

发表评论

匿名网友

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

确定