generateAccessToken method that clients can use to get a jwt token.
(data any)
| 814 | |
| 815 | // generateAccessToken method that clients can use to get a jwt token. |
| 816 | func (mw *GinJWTMiddleware) generateAccessToken(data any) (string, time.Time, error) { |
| 817 | // 1. Validate signing algorithm |
| 818 | signingMethod := jwt.GetSigningMethod(mw.SigningAlgorithm) |
| 819 | if signingMethod == nil { |
| 820 | return "", time.Time{}, ErrInvalidSigningAlgorithm |
| 821 | } |
| 822 | |
| 823 | token := jwt.New(signingMethod) |
| 824 | claims, ok := token.Claims.(jwt.MapClaims) |
| 825 | if !ok { |
| 826 | return "", time.Time{}, ErrFailedTokenCreation |
| 827 | } |
| 828 | |
| 829 | // 2. Define framework-controlled claims that PayloadFunc cannot overwrite |
| 830 | // Only claims that the framework calculates/manages internally are reserved. |
| 831 | // Standard JWT claims (sub, iss, aud, nbf, iat, jti) are allowed to be set by users |
| 832 | // via PayloadFunc to comply with RFC 7519 best practices. |
| 833 | frameworkClaims := map[string]bool{ |
| 834 | "exp": true, // Framework calculates expiration time |
| 835 | "orig_iat": true, // Framework uses this for refresh mechanism |
| 836 | } |
| 837 | |
| 838 | // 3. Safely add custom payload, avoiding framework-controlled field overwrites |
| 839 | if mw.PayloadFunc != nil { |
| 840 | for key, value := range mw.PayloadFunc(data) { |
| 841 | if !frameworkClaims[key] { |
| 842 | claims[key] = value |
| 843 | } |
| 844 | } |
| 845 | } |
| 846 | |
| 847 | // 4. Calculate expiration time using original data instead of claims |
| 848 | expire := mw.TimeFunc().Add(mw.TimeoutFunc(data)) |
| 849 | |
| 850 | // 5. Set required system claims |
| 851 | now := mw.TimeFunc() |
| 852 | claims[mw.ExpField] = expire.Unix() |
| 853 | claims["orig_iat"] = now.Unix() |
| 854 | |
| 855 | // 6. Sign the token |
| 856 | tokenString, err := mw.signedString(token) |
| 857 | if err != nil { |
| 858 | return "", time.Time{}, err |
| 859 | } |
| 860 | |
| 861 | return tokenString, expire, nil |
| 862 | } |
| 863 | |
| 864 | // TokenGenerator generates a complete token pair (access + refresh) with RFC 6749 compliance |
| 865 | func (mw *GinJWTMiddleware) TokenGenerator(ctx context.Context, data any) (*core.Token, error) { |