echobasicauth

package module
v1.5.0 Latest Latest
Warning

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

Go to latest
Published: Sep 22, 2026 License: LGPL-3.0 Imports: 11 Imported by: 0

README

echo basic auth

Basic Auth middleware with constant time equality checks and optional IP whitelisting for Echo framework. CIDRs are supported for IP whitelisting as well

Usage

plaintext:

auth := &echobasicauth.Auth{Login: "test", Password: "test", IPs: []string{"127.0.0.1", "10.0.0.0/24"}}
e.Use(echobasicauth.NewMiddleware(auth))
// or you can use echobasicauth.NewValidator(auth) if you want to define the middleware yourself

bcrypt:

auth := &echobasicauth.Auth{Login: "test", Password: "$2a$10$XajjQvNhvvRt5GSeFk1xFeyqRrsxkhBkUiQeg0dt.wU1qD4aFDcga", IPs: []string{"127.0.0.1", "10.0.0.0/24"}}

(and bcrypted Login supported as well, just in case)

With several Auth values, a request passes when any one of them accepts the credentials; an entry with an empty IPs list accepts its login from any IP.

NewMiddleware() with an empty auth list returns a middleware that rejects every request.

IP whitelist

Plain IP entries are normalized before matching, so ::1 and 0:0:0:0:0:0:0:1 (and upper/lowercase hex) are equivalent. CIDRs are supported as well.

By default, IP rules match the transport peer and client headers are ignored:

// no e.IPExtractor set (the default)
e.Use(echobasicauth.NewMiddleware(auth))

Proxied deployments can opt in to checking the original client instead of the proxy address:

e.IPExtractor = echo.ExtractIPFromXFFHeader()

Security note: this puts the IP gate on X-Forwarded-For. Echo's default extractor trusts loopback, link-local, and private peers, so any client that reaches the app directly from a private IP (office, VPN, same-host proxy) can set X-Forwarded-For to an allowlisted IP and pass the IP check; with the bare extractor the IP gate provides no protection against such clients. When combining the IP allowlist with an extractor, restrict the trust to your proxy range and disable the broad defaults:

proxyRange, _ := net.ParseCIDR("10.0.0.0/8") // your proxy range
e.IPExtractor = echo.ExtractIPFromXFFHeader(
	echo.TrustPrivateNet(false),
	echo.TrustLinkLocal(false),
	echo.TrustIPRange(proxyRange),
)
// keep the default TrustLoopback(true) only when your proxy sits on 127.0.0.1

SetIPs applies a new allowlist atomically for concurrent request processing; the exported IPs field is for config-time population, and reassigning it from another goroutine is a data race. Invalid entries never open the whitelist: an all-invalid list denies everybody, and Validate reports the typos, so they can fail the boot instead of the check:

if err := auth.Validate(); err != nil {
    return err
}

Failed attempts are logged at WARN with the anonymized client address; Echo's default level is ERROR, so raise it to see them: e.Logger.SetLevel(log.WARN).

IP validation without credentials
auth := &echobasicauth.Auth{IPs: []string{"127.0.0.1", "10.0.0.0/24"}}
if auth.AllowedIP(echobasicauth.ClientIP(c)) {
    // IP is allowed
}

Use ClientIP instead of c.RealIP(): it ignores client headers unless e.IPExtractor is set, and it returns an empty string for unparseable addresses, which the allowlist denies.

Documentation

Index

Constants

View Source
const ContextLoginKey = "echo-basic-auth.login"

ContextLoginKey is the key used to store the login after successful auth in the context

Variables

This section is empty.

Functions

func ClientIP added in v1.4.2

func ClientIP(c echo.Context) string

ClientIP resolves the client address, trusting forwarded headers only when echo.IPExtractor is set

func NewMiddleware

func NewMiddleware(auths ...*Auth) echo.MiddlewareFunc

NewMiddleware returns a new BasicAuth middleware instance

func NewValidator

func NewValidator(auths ...*Auth) middleware.BasicAuthValidator

NewValidator returns a new BasicAuthValidator

Types

type Auth

type Auth struct {
	Login    string   `json:"login" yaml:"login"` // Basic auth login
	Password string   `json:"password" yaml:"password"`
	IPs      []string `json:"ips" yaml:"ips"` // Allowed IPs and CIDRs; use SetIPs for runtime changes
	// contains filtered or unexported fields
}

Auth model

func (*Auth) AllowedIP added in v1.4.0

func (a *Auth) AllowedIP(ip string) bool

AllowedIP checks if the given IP is allowed by this Auth's IP rules

func (*Auth) Match added in v1.5.0

func (a *Auth) Match(login, password string) bool

Match checks if the given login and password match.

func (*Auth) SetIPs added in v1.5.0

func (a *Auth) SetIPs(ips []string)

SetIPs atomically replaces the IP allowlist, safe for concurrent request processing

func (*Auth) Validate added in v1.4.2

func (a *Auth) Validate() error

Validate reports allowlist entries that are neither an IP nor a CIDR, so a typo fails the boot

Jump to

Keyboard shortcuts

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