diff --git a/jwt/cookies.go b/jwt/cookies.go new file mode 100644 index 0000000..8a235d0 --- /dev/null +++ b/jwt/cookies.go @@ -0,0 +1,73 @@ +package jwt + +import ( + "github.com/pkg/errors" + "net/http" + "time" +) + +// Get the value of the access and refresh tokens +func GetTokenCookies( + r *http.Request, +) (acc string, ref string) { + accCookie, accErr := r.Cookie("access") + refCookie, refErr := r.Cookie("refresh") + var ( + accStr string = "" + refStr string = "" + ) + if accErr == nil { + accStr = accCookie.Value + } + if refErr == nil { + refStr = refCookie.Value + } + return accStr, refStr +} + +// Set a token with the provided details +func setToken( + w http.ResponseWriter, + token string, + scope string, + exp int64, + rememberme bool, + useSSL bool, +) { + tokenCookie := &http.Cookie{ + Name: scope, + Value: token, + Path: "/", + HttpOnly: true, + SameSite: http.SameSiteLaxMode, + Secure: useSSL, + } + if rememberme { + tokenCookie.Expires = time.Unix(exp, 0) + } + http.SetCookie(w, tokenCookie) +} + +// Generate new tokens for the subject and set them as cookies +func SetTokenCookies( + w http.ResponseWriter, + r *http.Request, + tokenGen *TokenGenerator, + subject int, + fresh bool, + rememberMe bool, + useSSL bool, +) error { + at, atexp, err := tokenGen.NewAccess(subject, fresh, rememberMe) + if err != nil { + return errors.Wrap(err, "jwt.GenerateAccessToken") + } + rt, rtexp, err := tokenGen.NewRefresh(subject, rememberMe) + if err != nil { + return errors.Wrap(err, "jwt.GenerateRefreshToken") + } + // Don't set the cookies until we know no errors occured + setToken(w, at, "access", atexp, rememberMe, useSSL) + setToken(w, rt, "refresh", rtexp, rememberMe, useSSL) + return nil +}