Module: Sinatra::JwtAuth::Helpers
- Defined in:
- lib/sinatra/jwt_auth.rb
Instance Method Summary collapse
-
#authenticate! ⇒ Object
Halts with 401 JSON if the Bearer token is missing, malformed, or fails cryptographic / claims verification.
-
#authenticate_or_401 ⇒ Object
Safe async-friendly authentication helper.
-
#current_user ⇒ Object
Returns the decoded payload Hash, or nil if the request has not been authenticated (or authentication failed).
-
#issue_token(payload, expires_in: 3600, extra_headers: {}) ⇒ Object
Mints a new token using the configured signing key + algorithm.
- #jwt_header ⇒ Object
- #jwt_payload ⇒ Object
Instance Method Details
#authenticate! ⇒ Object
Halts with 401 JSON if the Bearer token is missing, malformed, or fails cryptographic / claims verification. On success, sets DEPRECATED: This helper uses halt, which throws past Opal’s async boundary in # await: true routes. Use authenticate_or_401 instead and handle the returned [status, body] tuple explicitly.
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/sinatra/jwt_auth.rb', line 69 def authenticate! warn "DEPRECATION WARNING: authenticate! uses halt which is unsafe in async routes. Use authenticate_or_401 instead." token = extract_bearer_token ('missing bearer token') if token.nil? verify_key = settings.respond_to?(:jwt_verify_key) && settings.jwt_verify_key ? settings.jwt_verify_key : settings.jwt_secret algorithm = settings.respond_to?(:jwt_algorithm) ? settings.jwt_algorithm : 'HS256' begin payload, header = JWT.decode(token, verify_key, true, algorithm: algorithm).__await__ rescue JWT::ExpiredSignature ('token expired') rescue JWT::ImmatureSignature ('token not yet valid') rescue JWT::IncorrectAlgorithm ('algorithm mismatch') rescue JWT::VerificationError ('signature verification failed') rescue JWT::DecodeError => e ("invalid token: #{e.}") end @jwt_payload = payload @jwt_header = header payload end |
#authenticate_or_401 ⇒ Object
Safe async-friendly authentication helper. Returns [nil, payload] on success, or [401, json_body] on failure. Does NOT use halt — the caller is responsible for checking the status and returning early with status N; next(body).
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/sinatra/jwt_auth.rb', line 100 def authenticate_or_401 token = extract_bearer_token return [401, { 'error' => 'unauthorized', 'reason' => 'missing bearer token' }.to_json] if token.nil? verify_key = settings.respond_to?(:jwt_verify_key) && settings.jwt_verify_key ? settings.jwt_verify_key : settings.jwt_secret algorithm = settings.respond_to?(:jwt_algorithm) ? settings.jwt_algorithm : 'HS256' begin payload, header = JWT.decode(token, verify_key, true, algorithm: algorithm).__await__ rescue JWT::ExpiredSignature return [401, { 'error' => 'unauthorized', 'reason' => 'token expired' }.to_json] rescue JWT::ImmatureSignature return [401, { 'error' => 'unauthorized', 'reason' => 'token not yet valid' }.to_json] rescue JWT::IncorrectAlgorithm return [401, { 'error' => 'unauthorized', 'reason' => 'algorithm mismatch' }.to_json] rescue JWT::VerificationError return [401, { 'error' => 'unauthorized', 'reason' => 'signature verification failed' }.to_json] rescue JWT::DecodeError => e return [401, { 'error' => 'unauthorized', 'reason' => "invalid token: #{e.}" }.to_json] end @jwt_payload = payload @jwt_header = header [nil, payload] end |
#current_user ⇒ Object
Returns the decoded payload Hash, or nil if the request has not been authenticated (or authentication failed).
50 51 52 |
# File 'lib/sinatra/jwt_auth.rb', line 50 def current_user @jwt_payload end |
#issue_token(payload, expires_in: 3600, extra_headers: {}) ⇒ Object
Mints a new token using the configured signing key + algorithm. ‘expires_in` adds an `exp` claim in seconds from now; pass nil to leave it off. `extra_headers` is merged into the JWT header alongside the alg.
130 131 132 133 134 135 136 137 138 139 |
# File 'lib/sinatra/jwt_auth.rb', line 130 def issue_token(payload, expires_in: 3600, extra_headers: {}) sign_key = settings.respond_to?(:jwt_sign_key) && settings.jwt_sign_key ? settings.jwt_sign_key : settings.jwt_secret algorithm = settings.respond_to?(:jwt_algorithm) ? settings.jwt_algorithm : 'HS256' claims = payload.dup if expires_in claims['exp'] = Time.now.to_i + expires_in.to_i claims['iat'] = Time.now.to_i end JWT.encode(claims, sign_key, algorithm, extra_headers).__await__ end |
#jwt_header ⇒ Object
58 59 60 |
# File 'lib/sinatra/jwt_auth.rb', line 58 def jwt_header @jwt_header end |
#jwt_payload ⇒ Object
54 55 56 |
# File 'lib/sinatra/jwt_auth.rb', line 54 def jwt_payload @jwt_payload end |