beego:fix #685
move XsrfToken& CheckXsrfCookie to context
Showing
2 changed files
with
36 additions
and
20 deletions
| ... | @@ -20,6 +20,7 @@ import ( | ... | @@ -20,6 +20,7 @@ import ( |
| 20 | "time" | 20 | "time" |
| 21 | 21 | ||
| 22 | "github.com/astaxie/beego/middleware" | 22 | "github.com/astaxie/beego/middleware" |
| 23 | "github.com/astaxie/beego/utils" | ||
| 23 | ) | 24 | ) |
| 24 | 25 | ||
| 25 | // Http request context struct including BeegoInput, BeegoOutput, http.Request and http.ResponseWriter. | 26 | // Http request context struct including BeegoInput, BeegoOutput, http.Request and http.ResponseWriter. |
| ... | @@ -29,6 +30,7 @@ type Context struct { | ... | @@ -29,6 +30,7 @@ type Context struct { |
| 29 | Output *BeegoOutput | 30 | Output *BeegoOutput |
| 30 | Request *http.Request | 31 | Request *http.Request |
| 31 | ResponseWriter http.ResponseWriter | 32 | ResponseWriter http.ResponseWriter |
| 33 | _xsrf_token string | ||
| 32 | } | 34 | } |
| 33 | 35 | ||
| 34 | // Redirect does redirection to localurl with http header status code. | 36 | // Redirect does redirection to localurl with http header status code. |
| ... | @@ -113,3 +115,35 @@ func (ctx *Context) SetSecureCookie(Secret, name, value string, others ...interf | ... | @@ -113,3 +115,35 @@ func (ctx *Context) SetSecureCookie(Secret, name, value string, others ...interf |
| 113 | cookie := strings.Join([]string{vs, timestamp, sig}, "|") | 115 | cookie := strings.Join([]string{vs, timestamp, sig}, "|") |
| 114 | ctx.Output.Cookie(name, cookie, others...) | 116 | ctx.Output.Cookie(name, cookie, others...) |
| 115 | } | 117 | } |
| 118 | |||
| 119 | // XsrfToken creates a xsrf token string and returns. | ||
| 120 | func (ctx *Context) XsrfToken(key string, expire int64) string { | ||
| 121 | if ctx._xsrf_token == "" { | ||
| 122 | token, ok := ctx.GetSecureCookie(key, "_xsrf") | ||
| 123 | if !ok { | ||
| 124 | token = string(utils.RandomCreateBytes(32)) | ||
| 125 | ctx.SetSecureCookie(key, "_xsrf", token, expire) | ||
| 126 | } | ||
| 127 | ctx._xsrf_token = token | ||
| 128 | } | ||
| 129 | return ctx._xsrf_token | ||
| 130 | } | ||
| 131 | |||
| 132 | // CheckXsrfCookie checks xsrf token in this request is valid or not. | ||
| 133 | // the token can provided in request header "X-Xsrftoken" and "X-CsrfToken" | ||
| 134 | // or in form field value named as "_xsrf". | ||
| 135 | func (ctx *Context) CheckXsrfCookie() bool { | ||
| 136 | token := ctx.Input.Query("_xsrf") | ||
| 137 | if token == "" { | ||
| 138 | token = ctx.Request.Header.Get("X-Xsrftoken") | ||
| 139 | } | ||
| 140 | if token == "" { | ||
| 141 | token = ctx.Request.Header.Get("X-Csrftoken") | ||
| 142 | } | ||
| 143 | if token == "" { | ||
| 144 | ctx.Abort(403, "'_xsrf' argument missing from POST") | ||
| 145 | } else if ctx._xsrf_token != token { | ||
| 146 | ctx.Abort(403, "XSRF cookie does not match POST argument") | ||
| 147 | } | ||
| 148 | return true | ||
| 149 | } | ... | ... |
| ... | @@ -25,7 +25,6 @@ import ( | ... | @@ -25,7 +25,6 @@ import ( |
| 25 | 25 | ||
| 26 | "github.com/astaxie/beego/context" | 26 | "github.com/astaxie/beego/context" |
| 27 | "github.com/astaxie/beego/session" | 27 | "github.com/astaxie/beego/session" |
| 28 | "github.com/astaxie/beego/utils" | ||
| 29 | ) | 28 | ) |
| 30 | 29 | ||
| 31 | //commonly used mime-types | 30 | //commonly used mime-types |
| ... | @@ -477,18 +476,13 @@ func (c *Controller) SetSecureCookie(Secret, name, value string, others ...inter | ... | @@ -477,18 +476,13 @@ func (c *Controller) SetSecureCookie(Secret, name, value string, others ...inter |
| 477 | // XsrfToken creates a xsrf token string and returns. | 476 | // XsrfToken creates a xsrf token string and returns. |
| 478 | func (c *Controller) XsrfToken() string { | 477 | func (c *Controller) XsrfToken() string { |
| 479 | if c._xsrf_token == "" { | 478 | if c._xsrf_token == "" { |
| 480 | token, ok := c.GetSecureCookie(XSRFKEY, "_xsrf") | ||
| 481 | if !ok { | ||
| 482 | var expire int64 | 479 | var expire int64 |
| 483 | if c.XSRFExpire > 0 { | 480 | if c.XSRFExpire > 0 { |
| 484 | expire = int64(c.XSRFExpire) | 481 | expire = int64(c.XSRFExpire) |
| 485 | } else { | 482 | } else { |
| 486 | expire = int64(XSRFExpire) | 483 | expire = int64(XSRFExpire) |
| 487 | } | 484 | } |
| 488 | token = string(utils.RandomCreateBytes(32)) | 485 | c._xsrf_token = c.Ctx.XsrfToken(XSRFKEY, expire) |
| 489 | c.SetSecureCookie(XSRFKEY, "_xsrf", token, expire) | ||
| 490 | } | ||
| 491 | c._xsrf_token = token | ||
| 492 | } | 486 | } |
| 493 | return c._xsrf_token | 487 | return c._xsrf_token |
| 494 | } | 488 | } |
| ... | @@ -500,19 +494,7 @@ func (c *Controller) CheckXsrfCookie() bool { | ... | @@ -500,19 +494,7 @@ func (c *Controller) CheckXsrfCookie() bool { |
| 500 | if !c.EnableXSRF { | 494 | if !c.EnableXSRF { |
| 501 | return true | 495 | return true |
| 502 | } | 496 | } |
| 503 | token := c.GetString("_xsrf") | 497 | return c.Ctx.CheckXsrfCookie() |
| 504 | if token == "" { | ||
| 505 | token = c.Ctx.Request.Header.Get("X-Xsrftoken") | ||
| 506 | } | ||
| 507 | if token == "" { | ||
| 508 | token = c.Ctx.Request.Header.Get("X-Csrftoken") | ||
| 509 | } | ||
| 510 | if token == "" { | ||
| 511 | c.Ctx.Abort(403, "'_xsrf' argument missing from POST") | ||
| 512 | } else if c._xsrf_token != token { | ||
| 513 | c.Ctx.Abort(403, "XSRF cookie does not match POST argument") | ||
| 514 | } | ||
| 515 | return true | ||
| 516 | } | 498 | } |
| 517 | 499 | ||
| 518 | // XsrfFormHtml writes an input field contains xsrf token value. | 500 | // XsrfFormHtml writes an input field contains xsrf token value. | ... | ... |
-
Please register or sign in to post a comment