2023-03-10 18:00:00+00:00

One-Time Passwords (OTPs) sent via SMS or Email are crucial for securing critical workflows like registration, password resets, and high-value payments. However, OTP services are highly targeted by bad actors for SMS toll fraud and brute-force attempts. A secure OTP service requires strict rate limits, automated provider failovers, and low-latency storage.

Backing the service with Redis allows us to implement fast, atomic transaction checks while setting precise TTLs (Time-To-Live) on OTP codes.


1. Implementing Atomic Lockout in Redis

To prevent SMS spamming, we store two distinct keys in Redis for each mobile number: a cooling-down lock key (e.g., 60 seconds) and the actual OTP payload key (e.g., 5 minutes). We use Redis pipelines to check and set these values atomically:

func (s *OTPService) GenerateOTP(ctx context.Context, phone string) (string, error) {
    lockKey := fmt.Sprintf("otp:lock:%s", phone)
    otpKey := fmt.Sprintf("otp:code:%s", phone)
    
    // Check if lockout is active
    exists, _ := s.redis.Exists(ctx, lockKey).Result()
    if exists > 0 {
        return "", ErrLockoutActive
    }
    
    code := generateSixDigitCode()
    pipe := s.redis.TxPipeline()
    pipe.Set(ctx, lockKey, "1", 60*time.Second)
    pipe.Set(ctx, otpKey, code, 5*time.Minute)
    _, err := pipe.Exec(ctx)
    
    return code, err
}

2. Multi-Provider Failover Strategy

If an SMS gateway (e.g., Twilio or Infobip) experiences an outage, the service should automatically route messages to a secondary provider. We implement a Circuit Breaker pattern that tracks the success rate of outbound SMS calls and redirects traffic when failures exceed a set threshold.

Using Go's channels and goroutines, we can dispatch SMS requests asynchronously without blocking the user registration API response, keeping user latency minimal.

Atomic Redis Lua Scripts for OTP Verification & Attempt Counting

Evaluate OTP attempt increments, TTL checks, and code comparisons inside a single atomic Redis EVAL Lua script to prevent timing and brute-force race conditions.


About the Author — Hire Freelance Programmer Aldian Fazrihady

Aldian Fazrihady is a Top-Rated Senior Freelance Programmer, Freelance Full Stack Developer, and AI Application Engineer with 15+ years of production software engineering experience and Google Cloud Professional Cloud Architect & Data Engineer certifications. He specializes in building custom LLM & autonomous AI agents, RAG pipelines, Next.js/React PWAs, Python (Django/FastAPI), Go microservices, and serverless cloud infrastructure on Google Cloud Run and AWS.

Hire Aldian Fazrihady on Upwork | Book 1-Day Programming Service ($100 USD via Polar) | View Live AI Portfolio | Portfolio Directory | Send a Direct Message

Related Engineering Articles

Freelance Programmer Specializations & Category Hubs