-
Notifications
You must be signed in to change notification settings - Fork 95
/
jwt.rb
162 lines (132 loc) · 3.49 KB
/
jwt.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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
95
96
97
98
99
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# frozen-string-literal: true
require 'jwt'
require 'jwt/version'
module Rodauth
Feature.define(:jwt, :Jwt) do
depends :json
translatable_method :invalid_jwt_format_error_message, "invalid JWT format or claim in Authorization header"
auth_value_method :jwt_algorithm, "HS256"
auth_value_method :jwt_authorization_ignore, /\A(?:Basic|Digest) /
auth_value_method :jwt_authorization_remove, /\ABearer:?\s+/
auth_value_method :jwt_decode_opts, {}.freeze
auth_value_method :jwt_old_secret, nil
auth_value_method :jwt_session_key, nil
auth_value_method :jwt_symbolize_deeply?, false
auth_value_methods(
:jwt_secret,
:use_jwt?
)
auth_methods(
:jwt_session_hash,
:jwt_token,
:session_jwt,
:set_jwt_token
)
def_deprecated_alias :json_check_accept?, :jwt_check_accept?
def session
return @session if defined?(@session)
return super unless use_jwt?
s = {}
if jwt_token
unless session_data = jwt_payload
json_response[json_response_error_key] ||= invalid_jwt_format_error_message
_return_json_response
end
if jwt_session_key
session_data = session_data[jwt_session_key]
end
if session_data
if jwt_symbolize_deeply?
s = JSON.parse(JSON.fast_generate(session_data), :symbolize_names=>true)
elsif scope.opts[:sessions_convert_symbols]
s = session_data
else
session_data.each{|k,v| s[k.to_sym] = v}
end
end
end
@session = s
end
def clear_session
super
if use_jwt?
session.clear
set_jwt
end
end
def jwt_secret
raise ArgumentError, "jwt_secret not set"
end
def jwt_session_hash
jwt_session_key ? {jwt_session_key=>session} : session
end
def session_jwt
JWT.encode(jwt_session_hash, jwt_secret, jwt_algorithm)
end
def jwt_token
return @jwt_token if defined?(@jwt_token)
if (v = request.env['HTTP_AUTHORIZATION']) && v !~ jwt_authorization_ignore
@jwt_token = v.sub(jwt_authorization_remove, '')
end
end
def set_jwt_token(token)
response.headers['Authorization'] = token
end
def use_jwt?
use_json?
end
def use_json?
jwt_token || super
end
def valid_jwt?
!!(jwt_token && jwt_payload)
end
private
def check_csrf?
return false if use_jwt?
super
end
def _jwt_decode_opts
jwt_decode_opts
end
if JWT::VERSION::MAJOR > 2 || (JWT::VERSION::MAJOR == 2 && JWT::VERSION::MINOR >= 4)
def _jwt_decode_secrets
secrets = [jwt_secret, jwt_old_secret]
secrets.compact!
secrets
end
# :nocov:
else
def _jwt_decode_secrets
jwt_secret
end
# :nocov:
end
def jwt_payload
return @jwt_payload if defined?(@jwt_payload)
@jwt_payload = JWT.decode(jwt_token, _jwt_decode_secrets, true, _jwt_decode_opts.merge(:algorithm=>jwt_algorithm))[0]
rescue JWT::DecodeError => e
rescue_jwt_payload(e)
end
def rescue_jwt_payload(_)
@jwt_payload = false
end
def set_session_value(key, value)
super
set_jwt if use_jwt?
value
end
def remove_session_value(key)
value = super
set_jwt if use_jwt?
value
end
def return_json_response
set_jwt
super
end
def set_jwt
set_jwt_token(session_jwt)
end
end
end