| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- package form
- import (
- "crypto/rand"
- "crypto/subtle"
- "encoding/base64"
- "net/http"
- "time"
- )
- const (
- csrfCookieName = "_csrf"
- csrfFieldName = "_csrf"
- csrfTTL = time.Minute * 30
- csrfTokenSize = 32
- )
- /* csrfToken generates and configures a new double-submit CSRF token */
- func csrfToken(w http.ResponseWriter, r *http.Request, secure bool) string {
- /* get csrf cookie */
- cookie, err := r.Cookie(csrfCookieName)
- if err != nil {
- /* cookie does not yet exist, generate a new token */
- b := make([]byte, csrfTokenSize)
- rand.Read(b)
- token := base64.RawURLEncoding.EncodeToString(b)
- /* render new cookie */
- http.SetCookie(w, &http.Cookie{
- Name: csrfCookieName,
- Value: token,
- Path: "/",
- HttpOnly: false,
- SameSite: http.SameSiteLaxMode,
- Secure: secure,
- MaxAge: int(csrfTTL.Seconds()),
- })
- return token
- }
- /* return existing csrf token */
- return cookie.Value
- }
- /* csrfVerify checks if double-submit CSRF token is valid */
- func csrfVerify(r *http.Request) bool {
- /* get csrf form field value */
- formToken := r.PostFormValue(csrfFieldName)
- if formToken == "" {
- return false
- }
- /* get csrf cookie */
- cookie, err := r.Cookie(csrfCookieName)
- if err != nil {
- return false
- }
- /* compare the results */
- return subtle.ConstantTimeCompare([]byte(formToken), []byte(cookie.Value)) == 1
- }
|