Skip to content

Commit

Permalink
Fix local JWT auth (#111)
Browse files Browse the repository at this point in the history
  • Loading branch information
logan-stytch authored Dec 15, 2023
1 parent 101b6ac commit ccaaf30
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 14 deletions.
2 changes: 1 addition & 1 deletion lib/stytch/b2b_sessions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ def authenticate_jwt(
)
end

decoded_jwt = authenticate_jwt_local(session_jwt: session_jwt, authorization_check: authorization_check)
decoded_jwt = authenticate_jwt_local(session_jwt, max_token_age_seconds: max_token_age_seconds, authorization_check: authorization_check)
return decoded_jwt unless decoded_jwt.nil?

authenticate(
Expand Down
24 changes: 14 additions & 10 deletions lib/stytch/sessions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ def authenticate_jwt(
)
end

session = authenticate_jwt_local(session_jwt)
session = authenticate_jwt_local(session_jwt, max_token_age_seconds: max_token_age_seconds)
if !session.nil?
{ 'session' => session }
else
Expand All @@ -237,6 +237,7 @@ def authenticate_jwt(
# Parse a JWT and verify the signature locally (without calling /authenticate in the API)
# Uses the cached value to get the JWK but if it is unavailable, it calls the get_jwks()
# function to get the JWK
# This method never authenticates a JWT directly with the API
# If max_token_age_seconds is not supplied 300 seconds will be used as the default.
def authenticate_jwt_local(session_jwt, max_token_age_seconds: nil)
max_token_age_seconds = 300 if max_token_age_seconds.nil?
Expand All @@ -245,6 +246,7 @@ def authenticate_jwt_local(session_jwt, max_token_age_seconds: nil)
begin
decoded_token = JWT.decode session_jwt, nil, true,
{ jwks: @jwks_loader, iss: issuer, verify_iss: true, aud: @project_id, verify_aud: true, algorithms: ['RS256'] }

session = decoded_token[0]
iat_time = Time.at(session['iat']).to_datetime
return nil unless iat_time + max_token_age_seconds >= Time.now
Expand Down Expand Up @@ -272,15 +274,17 @@ def marshal_jwt_into_session(jwt)
reserved_claims = ['aud', 'exp', 'iat', 'iss', 'jti', 'nbf', 'sub', stytch_claim]
custom_claims = jwt.reject { |key, _| reserved_claims.include?(key) }
{
'session_id' => jwt[stytch_claim]['id'],
'user_id' => jwt['sub'],
'started_at' => jwt[stytch_claim]['started_at'],
'last_accessed_at' => jwt[stytch_claim]['last_accessed_at'],
# For JWTs that include it, prefer the inner expires_at claim.
'expires_at' => expires_at,
'attributes' => jwt[stytch_claim]['attributes'],
'authentication_factors' => jwt[stytch_claim]['authentication_factors'],
'custom_claims' => custom_claims
'session' => {
'session_id' => jwt[stytch_claim]['id'],
'user_id' => jwt['sub'],
'started_at' => jwt[stytch_claim]['started_at'],
'last_accessed_at' => jwt[stytch_claim]['last_accessed_at'],
# For JWTs that include it, prefer the inner expires_at claim.
'expires_at' => expires_at,
'attributes' => jwt[stytch_claim]['attributes'],
'authentication_factors' => jwt[stytch_claim]['authentication_factors'],
'custom_claims' => custom_claims
}
}
end
# ENDMANUAL(Sessions::authenticate_jwt)
Expand Down
2 changes: 1 addition & 1 deletion lib/stytch/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Stytch
VERSION = '7.0.1'
VERSION = '7.0.2'
end
4 changes: 2 additions & 2 deletions spec/stytch/sessions_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@

session = sessions.marshal_jwt_into_session(claims)
# The session expires an hour after `now`.
expect(session['expires_at']).to eq('2022-05-03T19:51:41Z')
expect(session['session']['expires_at']).to eq('2022-05-03T19:51:41Z')
end

it 'marshals JWT into session (old format)' do
Expand All @@ -73,7 +73,7 @@
session = sessions.marshal_jwt_into_session(claims)

# The "exp" claim is five minutes after `now`.
expect(session['expires_at']).to eq('2022-05-03T18:56:41Z')
expect(session['session']['expires_at']).to eq('2022-05-03T18:56:41Z')
end

private
Expand Down

0 comments on commit ccaaf30

Please sign in to comment.