From c0822297a1ccce2bbbe9a03bfeddc23fcb68ec86 Mon Sep 17 00:00:00 2001 From: pooulad Date: Sat, 30 Nov 2024 22:45:18 +0330 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=BE=20Create=20examples=20directory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- access_token.go | 20 +++++++++-- examples/main.go | 93 ++++++++++++++++++++++++++++++++++++++++++++++++ refresh_token.go | 2 +- 3 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 examples/main.go diff --git a/access_token.go b/access_token.go index 0eb6cea..c445bcc 100644 --- a/access_token.go +++ b/access_token.go @@ -32,14 +32,28 @@ func (t *authManager) GenerateAccessToken(ctx context.Context, uuid string, expi } jwtToken, err := jwt.NewWithClaims(TokenEncodingAlgorithm, claims).SignedString([]byte(t.opts.PrivateKey)) if err != nil { - return "", nil + return "", err } return jwtToken, nil } -// The GenerateAccessToken method is used to generate Stateless JWT Token. -// Notice that access tokens are not store at Redis Store and they are stateless! +// DecodeAccessToken parses and validates an access token (JWT) and returns its claims. +// It performs the following checks: +// 1. Verifies the token signature using the provided private key. +// 2. Checks the token's expiration time to ensure it is still valid. +// 3. Validates that the token type is specifically an AccessToken. +// +// If any of these checks fail, an appropriate error is returned. +// If the token is valid, the function returns the decoded AccessTokenClaims. +// +// Parameters: +// - ctx: The context for the operation (typically used for request cancellation). +// - token: The JWT access token to be decoded and validated. +// +// Returns: +// - *AccessTokenClaims: The claims embedded in the token, if valid. +// - error: Any error encountered during decoding or validation (e.g., invalid token, expired token). func (t *authManager) DecodeAccessToken(ctx context.Context, token string) (*AccessTokenClaims, error) { claims := &AccessTokenClaims{} jwtToken, err := jwt.ParseWithClaims(token, claims, diff --git a/examples/main.go b/examples/main.go new file mode 100644 index 0000000..5acd669 --- /dev/null +++ b/examples/main.go @@ -0,0 +1,93 @@ +package main + +import ( + "context" + "fmt" + "log" + "time" + + "github.com/go-redis/redis/v8" + auth_manager "github.com/tahadostifam/go-auth-manager" +) + +func main() { + // Initialize the Redis client + redisClient := redis.NewClient(&redis.Options{ + Addr: "localhost:6379", // Adjust Redis address if needed + DB: 0, // Default DB + }) + + // Initialize AuthManager with Redis client and options + authMgr := auth_manager.NewAuthManager(redisClient, auth_manager.AuthManagerOpts{ + PrivateKey: "supersecretkey", // A simple secret for JWT signing + }) + + // --- 1. Generating a Plain Token --- + // Create a sample payload for a plain token (e.g., email verification) + plainTokenPayload := &auth_manager.TokenPayload{ + UUID: "user-1234", // user UUID -> Unique ID of the user from the database or etc + CreatedAt: time.Now(), + TokenType: auth_manager.VerifyEmail, // Type of token (Verify Email) + } + + plainToken, err := authMgr.GeneratePlainToken(context.Background(), auth_manager.VerifyEmail, plainTokenPayload, time.Hour) + if err != nil { + log.Fatalf("Error generating plain token: %v", err) + } + fmt.Println("Generated Plain Token:", plainToken) + + // Decode the generated plain token + decodedPlainToken, err := authMgr.DecodePlainToken(context.Background(), plainToken, auth_manager.VerifyEmail) + if err != nil { + log.Fatalf("Error decoding plain token: %v", err) + } + fmt.Println("Decoded Plain Token Payload:", decodedPlainToken) + + // --- 2. Generating a Refresh Token --- + refreshTokenPayload := &auth_manager.RefreshTokenPayload{ + IPAddress: "192.168.1.1", + UserAgent: "Mozilla/5.0", + LoggedInAt: time.Duration(time.Now().Unix()) * time.Second, + } + + refreshToken, err := authMgr.GenerateRefreshToken(context.Background(), "user-1234", refreshTokenPayload, time.Hour*24) + if err != nil { + log.Fatalf("Error generating refresh token: %v", err) + } + fmt.Println("Generated Refresh Token:", refreshToken) + + // Decode the generated refresh token + decodedRefreshToken, err := authMgr.DecodeRefreshToken(context.Background(), "user-1234", refreshToken) + if err != nil { + log.Fatalf("Error decoding refresh token: %v", err) + } + fmt.Println("Decoded Refresh Token Payload:", decodedRefreshToken) + + // --- 3. Generating an Access Token --- + accessToken, err := authMgr.GenerateAccessToken(context.Background(), "user-1234", time.Hour) + if err != nil { + log.Fatalf("Error generating access token: %v", err) + } + fmt.Println("Generated Access Token:", accessToken) + + // Decode the generated access token + decodedAccessToken, err := authMgr.DecodeAccessToken(context.Background(), accessToken) + if err != nil { + log.Fatalf("Error decoding access token: %v", err) + } + fmt.Println("Decoded Access Token Claims:", decodedAccessToken) + + // --- 4. Destroying Plain Tokens --- + err = authMgr.DestroyPlainToken(context.Background(), plainToken) + if err != nil { + log.Fatalf("Error destroying plain token: %v", err) + } + fmt.Println("Plain token destroyed") + + // --- 5. Terminating All Refresh Tokens for a User --- + err = authMgr.TerminateRefreshTokens(context.Background(), "user-1234") + if err != nil { + log.Fatalf("Error terminating refresh tokens: %v", err) + } + fmt.Println("All refresh tokens terminated for user-1234") +} diff --git a/refresh_token.go b/refresh_token.go index a5cc925..f3e91ae 100644 --- a/refresh_token.go +++ b/refresh_token.go @@ -19,7 +19,7 @@ type RefreshTokenPayload struct { LoggedInAt time.Duration `json:"loggedInAt"` } -// The GenerateToken method generates a random string with base64 with a static byte length +// The GenerateRefreshToken method generates a random string with base64 with a static byte length // and stores it in the Redis store with provided expiration duration. func (t *authManager) GenerateRefreshToken(ctx context.Context, uuid string, payload *RefreshTokenPayload, expiresAt time.Duration) (string, error) { // Generate random string