#ruby-on-rails #ruby #heroku #jwt
#ruby-на-рельсах #рубиновый #героку #jwt
Вопрос:
У меня возникла проблема с моей реализацией ruby-jwt после обновления:
- Рельсы 4.1.6 — 4.2.11.3
- Ruby 2.1.4 — 2.6.6
- ruby-jwt gem с 1.3.0 до 2.2.2.
Он не будет декодировать токен после обновления и возвращает «Неверную информацию для входа». сообщение об ошибке от метода Login
класса decode
.
Это журнал успешного входа в исходную версию:
2020-12-04T09:51:42.814533 00:00 app[web.1]: I, [2020-12-04T09:51:42.814461 #8] INFO -- : Started POST "/api/p/v1/users/verify" for 54.210.159.54 at 2020-12-04 09:51:42 0000
2020-12-04T09:51:42.859735 00:00 app[web.1]: I, [2020-12-04T09:51:42.859575 #8] INFO -- : Processing by API::P::V1::UsersController#verify as JSON
2020-12-04T09:51:42.859766 00:00 app[web.1]: I, [2020-12-04T09:51:42.859707 #8] INFO -- : Parameters: {"login"=>"long token....................."}
2020-12-04T09:51:43.483446 00:00 heroku[router]: at=info method=POST path="/api/p/v1/users/verify" host=rails-api-app.herokuapp.com request_id=7f6dbb16-df78-4714-9b7c-b984905a2d6b fwd="54.210.159.54" dyno=web.1 connect=1ms service=674ms status=200 bytes=1457 protocol=https
2020-12-04T09:51:43.481107 00:00 app[web.1]: I, [2020-12-04T09:51:43.481016 #8] INFO -- : Completed 200 OK in 621ms (Views: 477.0ms | ActiveRecord: 25.7ms)
И вот ответ, который я получаю после того, как я создал обновленное приложение на Heroku:
2020-12-04T09:48:11.749514 00:00 app[web.1]: I, [2020-12-04T09:48:11.749444 #16] INFO -- : Started POST "/api/p/v1/users/verify" for 54.210.159.54 at 2020-12-04 09:48:11 0000
2020-12-04T09:48:11.818319 00:00 app[web.1]: I, [2020-12-04T09:48:11.818203 #16] INFO -- : Processing by API::P::V1::UsersController#verify as JSON
2020-12-04T09:48:11.818504 00:00 app[web.1]: I, [2020-12-04T09:48:11.818425 #16] INFO -- : Parameters: {"login"=>"long token....................."}
2020-12-04T09:48:11.892237 00:00 app[web.1]: I, [2020-12-04T09:48:11.892151 #16] INFO -- : Rendered ActiveModel::Serializer::Null with Hash (0.35ms)
2020-12-04T09:48:11.892681 00:00 app[web.1]: I, [2020-12-04T09:48:11.892583 #16] INFO -- : Completed 400 Bad Request in 74ms (Views: 22.9ms | ActiveRecord: 9.0ms)
2020-12-04T09:48:11.893186 00:00 app[web.1]: I, [2020-12-04T09:48:11.893118 #16] INFO -- : source=rack-timeout id=89c370e4-54e2-4442-83b2-d0c19b67c027 wait=6ms timeout=15000ms service=145ms state=completed
2020-12-04T09:48:11.894875 00:00 heroku[router]: at=info method=POST path="/api/p/v1/users/verify" host=rails-api-app.herokuapp.com request_id=89c370e4-54e2-4442-83b2-d0c19b67c027 fwd="54.210.159.54" dyno=web.1 connect=0ms service=151ms status=400 bytes=406 protocol=https
На стороне сервера:
и Encryptable
модуль с Login
классом и Decode
модулем:
module RailsAppName
module Encryptable
class Login
def self.decode(encrypted_payload, secret)
begin
new(Decoder.decode(encrypted_payload, secret))
rescue JWT::DecodeError
new({ valid: false, error_message: 'Invalid login information.' })
rescue JWT::ExpiredSignature
new({ valid: false, error_message: 'The signature has expired.' })
end
end
end
module Decoder
DECODER = JWT
EXPIRATION = 10
ENCRYPTION_ALGORITHM = "HS512"
def self.decode(encrypted_payload = {}, secret = "")
DECODER.decode(
encrypted_payload,
secret,
ENCRYPTION_ALGORITHM
).first
end
def self.encode(payload = {}, secret = "")
prepare!(payload)
DECODER.encode(
payload,
secret,
ENCRYPTION_ALGORITHM
)
end
private
def self.prepare!(payload)
payload.merge! exp: expiration_time
end
def self.expiration_time
EXPIRATION.minutes.from_now.to_i
end
end
end
end
Клиентская сторона:
def verify(email, password)
payload = { email: email, password: password }
encrypted_payload = { login: RubyClient::JWTEncryptable.encode(payload) }.to_json
response = public_client.post('/users/verify', { body: encrypted_payload })
if response.code == 200
{ user_token: RubyClient::JWTEncryptable.encode(response["user"]), user: response["user"] }
else
{ error: response['message'] }
end
end
Ответ №1:
После тщательного прочтения документации ruby-jwt.
Изменение decode
метода на следующий работает для меня:
module Decoder
DECODER = JWT
EXPIRATION = 10
ENCRYPTION_ALGORITHM = { algorithm: 'HS512' }
def self.decode(encrypted_payload = {}, secret = "")
DECODER.decode(
encrypted_payload,
secret,
true,
ENCRYPTION_ALGORITHM
).first
end
end