-
Notifications
You must be signed in to change notification settings - Fork 155
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: Support SameSite option (#123)
* Add SameSite with build constraied * Update options test * Fix after feedback * Add docs
- Loading branch information
Showing
8 changed files
with
360 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// +build !go1.11 | ||
// file for compatibility with go versions prior to 1.11 | ||
|
||
package csrf | ||
|
||
import ( | ||
"net/http" | ||
"time" | ||
|
||
"github.com/gorilla/securecookie" | ||
) | ||
|
||
// store represents the session storage used for CSRF tokens. | ||
type store interface { | ||
// Get returns the real CSRF token from the store. | ||
Get(*http.Request) ([]byte, error) | ||
// Save stores the real CSRF token in the store and writes a | ||
// cookie to the http.ResponseWriter. | ||
// For non-cookie stores, the cookie should contain a unique (256 bit) ID | ||
// or key that references the token in the backend store. | ||
// csrf.GenerateRandomBytes is a helper function for generating secure IDs. | ||
Save(token []byte, w http.ResponseWriter) error | ||
} | ||
|
||
// cookieStore is a signed cookie session store for CSRF tokens. | ||
type cookieStore struct { | ||
name string | ||
maxAge int | ||
secure bool | ||
httpOnly bool | ||
path string | ||
domain string | ||
sc *securecookie.SecureCookie | ||
sameSite SameSiteMode | ||
} | ||
|
||
// Get retrieves a CSRF token from the session cookie. It returns an empty token | ||
// if decoding fails (e.g. HMAC validation fails or the named cookie doesn't exist). | ||
func (cs *cookieStore) Get(r *http.Request) ([]byte, error) { | ||
// Retrieve the cookie from the request | ||
cookie, err := r.Cookie(cs.name) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
token := make([]byte, tokenLength) | ||
// Decode the HMAC authenticated cookie. | ||
err = cs.sc.Decode(cs.name, cookie.Value, &token) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return token, nil | ||
} | ||
|
||
// Save stores the CSRF token in the session cookie. | ||
func (cs *cookieStore) Save(token []byte, w http.ResponseWriter) error { | ||
// Generate an encoded cookie value with the CSRF token. | ||
encoded, err := cs.sc.Encode(cs.name, token) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
cookie := &http.Cookie{ | ||
Name: cs.name, | ||
Value: encoded, | ||
MaxAge: cs.maxAge, | ||
HttpOnly: cs.httpOnly, | ||
Secure: cs.secure, | ||
Path: cs.path, | ||
Domain: cs.domain, | ||
} | ||
|
||
// Set the Expires field on the cookie based on the MaxAge | ||
// If MaxAge <= 0, we don't set the Expires attribute, making the cookie | ||
// session-only. | ||
if cs.maxAge > 0 { | ||
cookie.Expires = time.Now().Add( | ||
time.Duration(cs.maxAge) * time.Second) | ||
} | ||
|
||
// Write the authenticated cookie to the response. | ||
http.SetCookie(w, cookie) | ||
|
||
return nil | ||
} |
Oops, something went wrong.