package jwt import ( "github.com/pkg/errors" "net/http" "time" ) // GetTokenCookies extracts access and refresh tokens from HTTP request cookies. // Returns empty strings for any cookies that don't exist. // // Returns: // - acc: The access token value from the "access" cookie (empty if not found) // - ref: The refresh token value from the "refresh" cookie (empty if not found) 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 } // setToken is an internal helper that sets a token cookie with the specified parameters. // The cookie is HttpOnly for security and uses SameSite=Lax mode. // // Parameters: // - w: HTTP response writer to set the cookie on // - token: The token value to store in the cookie // - scope: The cookie name ("access" or "refresh") // - exp: Unix timestamp when the token expires // - rememberme: If true, sets cookie expiration; if false, cookie is session-only // - useSSL: If true, marks cookie as Secure (HTTPS only) 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) } // SetTokenCookies generates new access and refresh tokens for a user and sets them as HTTP cookies. // This is a convenience function that combines token generation with cookie setting. // Cookies are HttpOnly and use SameSite=Lax for security. // // Parameters: // - w: HTTP response writer to set cookies on // - r: HTTP request (unused but kept for API consistency) // - tokenGen: The TokenGenerator to use for creating tokens // - subject: The user ID to generate tokens for // - fresh: If true, marks the access token as fresh for sensitive operations // - rememberMe: If true, tokens persist beyond browser session // - useSSL: If true, marks cookies as Secure (HTTPS only) // // Returns an error if token generation fails. Cookies are only set if both tokens // are generated successfully. 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 }