Skip to content

Commit

Permalink
Merge pull request #4 from pooulad/main
Browse files Browse the repository at this point in the history
👾 Refactor examples and improve code documentation
  • Loading branch information
tahadostifam authored Dec 1, 2024
2 parents 5fb5242 + c082229 commit 76e1dbf
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 4 deletions.
20 changes: 17 additions & 3 deletions access_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
93 changes: 93 additions & 0 deletions examples/main.go
Original file line number Diff line number Diff line change
@@ -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")
}
2 changes: 1 addition & 1 deletion refresh_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 76e1dbf

Please sign in to comment.