Created
March 14, 2026 15:12
-
-
Save mohashari/b46d87053c985fbc2d46cb6769eaf03d to your computer and use it in GitHub Desktop.
Code snippets — Jwt Authentication Deep Dive
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func RefreshTokens(refreshToken string) (accessToken, newRefreshToken string, err error) { | |
| // Validate refresh token against database | |
| stored, err := db.GetRefreshToken(ctx, refreshToken) | |
| if err != nil || stored.ExpiresAt.Before(time.Now()) { | |
| return "", "", errors.New("invalid or expired refresh token") | |
| } | |
| // Generate new tokens | |
| accessToken, _ = GenerateAccessToken(stored.UserID) | |
| newRefreshToken = generateSecureRandom(32) | |
| // Rotate: delete old, store new (refresh token rotation) | |
| db.DeleteRefreshToken(ctx, refreshToken) | |
| db.StoreRefreshToken(ctx, stored.UserID, newRefreshToken, 7*24*time.Hour) | |
| return accessToken, newRefreshToken, nil | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // BAD - anyone with the token can read this | |
| { "sub": "42", "credit_card": "4111-1111-1111-1111" } | |
| // GOOD - minimal claims only | |
| { "sub": "42", "role": "user" } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 1. Login → server returns: | |
| - access_token (15 min TTL, stored in memory) | |
| - refresh_token (7 days TTL, stored in httpOnly cookie) | |
| 2. API requests use access_token in Authorization header | |
| 3. When access_token expires: | |
| - Client sends refresh_token | |
| - Server validates and issues new access_token + rotated refresh_token | |
| 4. Logout → invalidate refresh_token in database |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // WRONG - vulnerable to alg:none attack | |
| jwt.Parse(tokenString, func(t *jwt.Token) (interface{}, error) { | |
| return signingKey, nil | |
| }) | |
| // RIGHT - verify algorithm first | |
| jwt.ParseWithClaims(tokenString, &Claims{}, func(t *jwt.Token) (interface{}, error) { | |
| if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok { | |
| return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"]) | |
| } | |
| return signingKey, nil | |
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| jwt.ParseWithClaims(tokenString, &Claims{}, | |
| keyFunc, | |
| jwt.WithExpirationRequired(), | |
| jwt.WithIssuer("myapp"), | |
| jwt.WithAudience("myapp-api"), | |
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package auth | |
| import ( | |
| "time" | |
| "github.com/golang-jwt/jwt/v5" | |
| ) | |
| type Claims struct { | |
| UserID string `json:"sub"` | |
| Email string `json:"email"` | |
| Role string `json:"role"` | |
| jwt.RegisteredClaims | |
| } | |
| var signingKey = []byte(os.Getenv("JWT_SECRET")) | |
| func GenerateToken(userID, email, role string) (string, error) { | |
| claims := Claims{ | |
| UserID: userID, | |
| Email: email, | |
| Role: role, | |
| RegisteredClaims: jwt.RegisteredClaims{ | |
| ExpiresAt: jwt.NewNumericDate(time.Now().Add(15 * time.Minute)), | |
| IssuedAt: jwt.NewNumericDate(time.Now()), | |
| Issuer: "myapp", | |
| }, | |
| } | |
| token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) | |
| return token.SignedString(signingKey) | |
| } | |
| func ValidateToken(tokenString string) (*Claims, error) { | |
| token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(t *jwt.Token) (interface{}, error) { | |
| // CRITICAL: verify the signing method | |
| if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok { | |
| return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"]) | |
| } | |
| return signingKey, nil | |
| }) | |
| if err != nil { | |
| return nil, err | |
| } | |
| claims, ok := token.Claims.(*Claims) | |
| if !ok || !token.Valid { | |
| return nil, fmt.Errorf("invalid token") | |
| } | |
| return claims, nil | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // WRONG | |
| localStorage.setItem('access_token', token); | |
| // RIGHT - store in memory (React state, etc.) | |
| setAccessToken(token); | |
| // Refresh token in httpOnly cookie (set by server) | |
| // document.cookie cannot access httpOnly cookies |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Header | |
| { "alg": "HS256", "typ": "JWT" } | |
| // Payload | |
| { | |
| "sub": "1234567890", | |
| "name": "John Doe", | |
| "iat": 1516239022, | |
| "exp": 1516242622 | |
| } | |
| // Signature = HMAC_SHA256(base64(header) + "." + base64(payload), secret) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Generate a strong secret | |
| openssl rand -hex 32 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment