Module: Leash::Auth
- Defined in:
- lib/leash/auth.rb
Overview
Framework-agnostic server auth helper.
Works with any request object that exposes either:
- request.cookies (Hash) — Rack / Rails / Sinatra
- request.env['HTTP_COOKIE'] or request.get_header('HTTP_COOKIE') — raw Rack env
Does NOT require rails, sinatra, or rack.
Constant Summary collapse
- COOKIE_NAME =
"leash-auth"
Class Method Summary collapse
-
.authenticated?(request) ⇒ Boolean
Check whether the request carries a valid leash-auth cookie.
- .build_user(payload) ⇒ Object private
- .decode_token(token) ⇒ Object private
- .extract_token(request) ⇒ Object private
-
.get_user(request) ⇒ Leash::User
Read the leash-auth JWT from the request, decode it, and return a User.
- .parse_cookie_header(header) ⇒ Object private
Class Method Details
.authenticated?(request) ⇒ Boolean
Check whether the request carries a valid leash-auth cookie.
67 68 69 70 71 72 |
# File 'lib/leash/auth.rb', line 67 def authenticated?(request) get_user(request) true rescue AuthError false end |
.build_user(payload) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/leash/auth.rb', line 128 def build_user(payload) id = payload["id"] || payload["sub"] email = payload["email"] raise AuthError, "Token payload missing required fields (id/sub, email)" unless id && email User.new( id: id, email: email, name: payload["name"], picture: payload["picture"] ) end |
.decode_token(token) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/leash/auth.rb', line 113 def decode_token(token) secret = ENV["LEASH_JWT_SECRET"] if secret && !secret.empty? decoded = JWT.decode(token, secret, true, algorithms: ["HS256"]) else decoded = JWT.decode(token, nil, false) end decoded.first rescue JWT::ExpiredSignature raise AuthError, "Token has expired" rescue JWT::DecodeError => e raise AuthError, "Invalid token: #{e.}" end |
.extract_token(request) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/leash/auth.rb', line 75 def extract_token(request) # Strategy 1: request.cookies hash (Rack / Rails / Sinatra) if request.respond_to?(:cookies) = request. if .is_a?(Hash) value = [COOKIE_NAME] || [COOKIE_NAME.to_sym] return value if value end end # Strategy 2: raw Cookie header from env or get_header raw = nil if request.respond_to?(:env) && request.env.is_a?(Hash) raw = request.env["HTTP_COOKIE"] end if raw.nil? && request.respond_to?(:get_header) begin raw = request.get_header("HTTP_COOKIE") rescue StandardError nil end end (raw) if raw end |
.get_user(request) ⇒ Leash::User
Read the leash-auth JWT from the request, decode it, and return a User.
55 56 57 58 59 60 61 |
# File 'lib/leash/auth.rb', line 55 def get_user(request) token = extract_token(request) raise AuthError, "Missing leash-auth cookie" if token.nil? || token.empty? payload = decode_token(token) build_user(payload) end |
.parse_cookie_header(header) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
102 103 104 105 106 107 108 109 110 |
# File 'lib/leash/auth.rb', line 102 def (header) return nil if header.nil? header.split(";").each do |pair| key, value = pair.strip.split("=", 2) return value if key == COOKIE_NAME end nil end |