Files

45 lines
1.1 KiB
Go

package crypto
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"fmt"
"strconv"
"strings"
"time"
)
// token = base64(user) "." expiryUnix "." base64(hmac)
func SignSession(secret []byte, user string, expiry time.Time) string {
payload := base64.RawURLEncoding.EncodeToString([]byte(user)) + "." +
strconv.FormatInt(expiry.Unix(), 10)
return payload + "." + sign(secret, payload)
}
func VerifySession(secret []byte, token string, now time.Time) (string, bool) {
parts := strings.Split(token, ".")
if len(parts) != 3 {
return "", false
}
payload := parts[0] + "." + parts[1]
if !hmac.Equal([]byte(parts[2]), []byte(sign(secret, payload))) {
return "", false
}
exp, err := strconv.ParseInt(parts[1], 10, 64)
if err != nil || now.Unix() > exp {
return "", false
}
user, err := base64.RawURLEncoding.DecodeString(parts[0])
if err != nil {
return "", false
}
return string(user), true
}
func sign(secret []byte, payload string) string {
m := hmac.New(sha256.New, secret)
fmt.Fprint(m, payload)
return base64.RawURLEncoding.EncodeToString(m.Sum(nil))
}