RapidGo
No results found

Authentication

JWT tokens, OAuth2 social login, and TOTP two-factor authentication.

RapidGo provides three authentication mechanisms: JWT tokens for stateless API auth, OAuth2 for social login, and TOTP for two-factor authentication.

JWT Authentication

The auth package handles JWT token generation and validation using HMAC-SHA256.

Configuration

JWT_SECRET=your-secret-key-at-least-32-bytes-long
JWT_EXPIRY=3600    # Token lifetime in seconds (default: 1 hour)

Generating Tokens

import "github.com/RAiWorks/RapidGo/v2/core/auth"

// Generate a JWT for a user
token, err := auth.GenerateToken(user.ID)
if err != nil {
    // handle error
}
c.JSON(http.StatusOK, gin.H{"token": token})

Validating Tokens

claims, err := auth.ValidateToken(tokenString)
if err != nil {
    c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid token"})
    return
}
userID := uint(claims["user_id"].(float64))

Token Claims

Generated tokens include:

Claim Description
user_id The authenticated user's ID
exp Expiration timestamp (Unix)
iat Issued-at timestamp (Unix)

Auth Middleware

Apply the built-in auth middleware to protect routes:

api := r.Group("/api")
api.Use(middleware.Auth())  // Validates JWT from Authorization header

api.Get("/profile", func(c *gin.Context) {
    userID := c.GetUint("user_id")  // Set by middleware
    // ...
})

OAuth2 Social Login

The oauth package provides OAuth2 integration with pre-configured providers for Google and GitHub, plus support for custom providers.

Pre-configured Providers

import "github.com/RAiWorks/RapidGo/v2/core/oauth"

// Google
google := oauth.Google(clientID, clientSecret, redirectURL)

// GitHub
github := oauth.GitHub(clientID, clientSecret, redirectURL)

Custom Providers

provider := oauth.NewProvider(
    "gitlab",
    clientID, clientSecret, redirectURL,
    []string{"read_user"},
    "https://gitlab.com/oauth/authorize",
    "https://gitlab.com/oauth/token",
    "https://gitlab.com/api/v4/user",
    func(raw map[string]any) oauth.UserInfo {
        return oauth.UserInfo{
            ID:    fmt.Sprintf("%v", raw["id"]),
            Email: raw["email"].(string),
            Name:  raw["name"].(string),
        }
    },
)

OAuth2 Flow

// Step 1: Redirect to provider
func OAuthRedirect(c *gin.Context) {
    state := oauth.GenerateState()
    // Store state in session for CSRF protection
    session["oauth_state"] = state
    c.Redirect(http.StatusTemporaryRedirect, provider.AuthCodeURL(state))
}

// Step 2: Handle callback
func OAuthCallback(c *gin.Context) {
    code := c.Query("code")
    token, err := provider.Exchange(c.Request.Context(), code)
    if err != nil { /* handle error */ }

    user, err := provider.FetchUser(c.Request.Context(), token)
    if err != nil { /* handle error */ }

    // user.ID, user.Email, user.Name, user.AvatarURL
    // Create or find local user, issue JWT, etc.
}

TOTP Two-Factor Authentication

The totp package implements Time-based One-Time Passwords compatible with Google Authenticator, Authy, and similar apps.

Setup 2FA

import "github.com/RAiWorks/RapidGo/v2/core/totp"

// Generate a TOTP secret for the user
key, err := totp.GenerateKey("RapidGo", user.Email)
if err != nil { /* handle error */ }

// key.Secret — store this in the user's record (encrypted)
// key.URL    — use this to generate a QR code for the authenticator app

Verify Codes

valid := totp.ValidateCode(user.TOTPSecret, codeFromUser)
if !valid {
    c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid 2FA code"})
    return
}

Backup Codes

// Generate 10 backup codes
codes, err := totp.GenerateBackupCodes(10)
// Returns: ["A1B2-C3D4", "E5F6-G7H8", ...]

// Hash codes before storing
for _, code := range codes {
    hash, _ := totp.HashBackupCode(code)
    // Store hash in database
}

// Verify a backup code
valid := totp.VerifyBackupCode(userInput, storedHash)