-
Notifications
You must be signed in to change notification settings - Fork 0
/
cookie_manager.go
104 lines (88 loc) · 2.27 KB
/
cookie_manager.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package oidcauth
import (
"net/http"
"time"
"github.com/gorilla/securecookie"
)
type CookieOptions struct {
Path string
Secure bool
HttpOnly bool
Domain string
SameSite http.SameSite
Duration time.Duration
}
func (co *CookieOptions) NewCookie(name, value string) *http.Cookie {
var expires time.Time
if co.Duration != 0 {
expires = time.Now().Add(co.Duration)
}
return &http.Cookie{
Name: name,
Value: value,
Path: co.Path,
Domain: co.Domain,
Expires: expires,
Secure: co.Secure,
HttpOnly: co.HttpOnly,
SameSite: co.SameSite,
}
}
type CookieManager struct {
securecookie *securecookie.SecureCookie
cookieOptions CookieOptions
}
func NewDefaultCookieOptions() *CookieOptions {
return &CookieOptions{
Path: "/",
Secure: true,
HttpOnly: true,
SameSite: http.SameSiteLaxMode,
}
}
func NewCookieHandler(hashKey, encryptKey []byte) *CookieManager {
return NewCookieHandlerWithOptions(hashKey, encryptKey, NewDefaultCookieOptions())
}
func NewCookieHandlerWithOptions(hashKey []byte, encryptKey []byte, options *CookieOptions) *CookieManager {
sc := securecookie.New(hashKey, encryptKey)
sc.MaxLength(0)
if options == nil {
options = NewDefaultCookieOptions()
}
return &CookieManager{
securecookie: sc,
cookieOptions: *options,
}
}
func (c *CookieManager) Set(w http.ResponseWriter, r *http.Request, name string, value any, opts ...func(*http.Cookie)) error {
encodedValue, err := c.securecookie.Encode(name, value)
if err != nil {
return err
}
cookie := c.cookieOptions.NewCookie(name, encodedValue)
for _, opt := range opts {
opt(cookie)
}
SetCookie(w, r, cookie)
return nil
}
func (c *CookieManager) Get(r *http.Request, name string, dstValue any) (bool, error) {
cookies := getCookies(r, name)
if len(cookies) == 0 {
return false, nil
}
encodedValue := concatCookieValues(cookies)
return true, c.securecookie.Decode(name, encodedValue, dstValue)
}
func (c *CookieManager) Delete(w http.ResponseWriter, r *http.Request, name string) {
cookies := getCookies(r, name)
if len(cookies) == 0 {
return
}
for _, cookie := range cookies {
deletionCookie := c.cookieOptions.NewCookie(cookie.Name, "")
deletionCookie.Expires = time.Time{}
deletionCookie.MaxAge = -1
http.SetCookie(w, deletionCookie)
}
}