...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package oauth2
16
17 import (
18 "crypto/rand"
19 "crypto/subtle"
20 "encoding/hex"
21 "net/http"
22
23 "github.com/alexedwards/scs"
24 "github.com/pkg/errors"
25 )
26
27 var (
28 DefaultSessionKey = "oauth2.state"
29 )
30
31 type SessionStateStore struct {
32 Sessions *scs.Manager
33 }
34
35 func (s *SessionStateStore) GenerateState(w http.ResponseWriter, r *http.Request) (string, error) {
36 sess := s.Sessions.Load(r)
37
38 b := make([]byte, 20)
39 if _, err := rand.Read(b); err != nil {
40 return "", errors.Wrap(err, "failed to generate state value")
41 }
42
43 state := hex.EncodeToString(b)
44 return state, sess.PutString(w, DefaultSessionKey, state)
45 }
46
47 func (s *SessionStateStore) VerifyState(r *http.Request, expected string) (bool, error) {
48 sess := s.Sessions.Load(r)
49
50 state, err := sess.GetString(DefaultSessionKey)
51 if err != nil {
52 return false, err
53 }
54
55 return subtle.ConstantTimeCompare([]byte(expected), []byte(state)) == 1, nil
56 }
57
View as plain text