Module: Sessions::IpAddress
- Defined in:
- lib/sessions/ip_address.rb
Overview
IP capture, normalization and (optional) anonymization.
Capture goes through ‘config.ip_resolver` (default `request.remote_ip`, which honors Rails’ trusted_proxies — see the README’s “Behind Cloudflare” section for CDN setups). Every address is IPAddr-normalized before persistence (canonical form, garbage rejected) and, when ‘config.ip_mode = :truncated`, anonymized BEFORE it ever touches disk: the last IPv4 octet / the last 80 IPv6 bits are zeroed — the Google Analytics precedent, and the reason the column can be shown to a GDPR auditor with a straight face.
Constant Summary collapse
- MAX_LENGTH =
45 chars covers the maximum IPv6 textual form including IPv4-mapped addresses (“::ffff:255.255.255.255”) — the portable column size used across sqlite/mysql/postgres.
45- IPV4_PREFIX =
Anonymization prefix lengths (bits kept): IPv4 /24 zeroes the last octet; IPv6 /48 zeroes the last 80 bits.
24- IPV6_PREFIX =
48
Class Method Summary collapse
- .normalize(raw) ⇒ Object
-
.resolve(request) ⇒ Object
The client IP for this request, resolved + normalized + anonymized per configuration.
- .truncate(address) ⇒ Object
Class Method Details
.normalize(raw) ⇒ Object
42 43 44 45 46 47 48 49 50 |
# File 'lib/sessions/ip_address.rb', line 42 def normalize(raw) return nil if raw.to_s.strip.empty? address = IPAddr.new(raw.to_s.strip[0, MAX_LENGTH]) address = truncate(address) if Sessions.config.ip_mode == :truncated address.to_s rescue ArgumentError # IPAddr::Error included — it subclasses ArgumentError nil end |
.resolve(request) ⇒ Object
The client IP for this request, resolved + normalized + anonymized per configuration. Returns nil for unresolvable/garbage input — a nil IP must never block a login write.
32 33 34 35 36 37 38 39 40 |
# File 'lib/sessions/ip_address.rb', line 32 def resolve(request) return nil unless request raw = Sessions.config.ip_resolver.call(request) normalize(raw) rescue StandardError => e Sessions.warn("ip resolution failed: #{e.class}: #{e.}") nil end |
.truncate(address) ⇒ Object
52 53 54 |
# File 'lib/sessions/ip_address.rb', line 52 def truncate(address) address.mask(address.ipv4? ? IPV4_PREFIX : IPV6_PREFIX) end |