locker

package
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 16, 2026 License: BSD-3-Clause Imports: 5 Imported by: 0

Documentation

Overview

Package locker provides rate limiting and attempt counting with Redis storage.

It's useful for limiting login attempts, API rate limiting, or any scenario where you need to track and limit the number of operations within a time window.

Hertz Backend Setup

// Initialize locker with Redis client
lock := locker.New(redisClient)

// Login endpoint with attempt limiting
h.POST("/auth/login", func(ctx context.Context, c *app.RequestContext) {
	username := c.Query("username")
	lockKey := "login:" + username

	// Check if already locked (max 5 attempts)
	if err := lock.Check(ctx, lockKey, 5); err != nil {
		if errors.Is(err, locker.ErrLocked) {
			c.JSON(429, utils.H{"error": "too many attempts, try again later"})
			return
		}
	}

	// Validate credentials...
	if !validCredentials {
		// Increment attempt counter (5 minute window)
		lock.Increment(ctx, lockKey, 5*time.Minute)
		c.JSON(401, utils.H{"error": "invalid credentials"})
		return
	}

	// Success - clear the counter
	lock.Delete(ctx, lockKey)
	c.JSON(200, utils.H{"token": token})
})

How It Works

  • Increment: Atomically increments counter, sets TTL on first call
  • Check: Returns ErrLocked if counter >= max
  • Delete: Clears the counter (e.g., after successful login)

Security Notes

  • Use appropriate TTL based on your security requirements
  • Consider using IP + username combination for login limiting
  • The counter auto-expires after TTL, no manual cleanup needed

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotExists = errors.New("locker: counter does not exist")
	ErrLocked    = errors.New("locker: limit exceeded")
)

Errors returned by locker functions.

Functions

This section is empty.

Types

type Locker

type Locker struct {
	// RDb is the Redis client for storing counters.
	RDb *redis.Client
	// Prefix is the key prefix for all locker keys (default: "locker").
	Prefix string
}

Locker provides rate limiting and attempt counting with Redis storage.

func New

func New(rdb *redis.Client, options ...Option) *Locker

New creates a new Locker instance with the given Redis client.

func (*Locker) Check added in v1.0.0

func (x *Locker) Check(ctx context.Context, name string, max int64) error

Check verifies if the counter has exceeded the maximum allowed value. Returns nil if counter < max or counter doesn't exist. Returns ErrLocked if counter >= max.

func (*Locker) Delete

func (x *Locker) Delete(ctx context.Context, name string) int64

Delete removes the counter for the given name. Returns the number of keys deleted (0 or 1). Typically called after successful authentication to reset the counter.

func (*Locker) Get added in v1.0.0

func (x *Locker) Get(ctx context.Context, name string) (int64, error)

Get returns the current counter value for the given name. Returns 0 if the counter doesn't exist.

func (*Locker) Increment added in v1.0.0

func (x *Locker) Increment(ctx context.Context, name string, ttl time.Duration) (int64, error)

Increment atomically increments the counter for the given name. On the first call, it sets the TTL for the counter. Subsequent calls within the TTL window only increment without resetting TTL. Returns the current count after incrementing.

func (*Locker) Key

func (x *Locker) Key(name string) string

Key generates the full Redis key for a locker name. Format: "{prefix}:{name}"

type Option added in v1.0.0

type Option func(x *Locker)

Option is a function that configures a Locker instance.

func SetPrefix added in v1.0.0

func SetPrefix(v string) Option

SetPrefix sets the Redis key prefix for locker keys. Default is "locker", resulting in keys like "locker:login:user@example.com".

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL