У меня есть API Rails, использующий JWT для входа в систему. login работает с токеном, сгенерированным и сохраненным в локальном хранилище. Однако возникли проблемы с авторизацией действий контроллера на основе декодирования токена.
authorize_request используется в качестве предварительного действия в различных контроллерах.
вот действие authorize_request, определенное в application_controller:
класс ApplicationController < ActionController::API
def not_found
render json: { error: 'not_found' }
end
def authorize_request
header = request.headers['Authorization']
header = header.split(' ').last if header
puts "header is #{header}"
begin
@decoded = JsonWebToken.decode(header)
puts "decoded header is #{@decoded}"
@current_user = User.find(@decoded[:user_id])
puts "current_user is #{@current_user}"
rescue ActiveRecord::RecordNotFound => e
render json: { errors: e.message }, status: :unauthorized
rescue JWT::DecodeError => e
render json: { errors: e.message }, status: :unauthorized
end
end
end
Вот метод декодирования класса JsonWebToken:
class JsonWebToken
SECRET_KEY = Rails.application.secrets.secret_key_base
def self.encode(payload, exp = 24.hours.from_now)
payload[:exp] = exp.to_i
JWT.encode(payload, SECRET_KEY)
end
def self.decode(token)
puts("decoding token: #{token}")
decoded = JWT.decode(token, SECRET_KEY)
puts("decoded is #{decoded}")
HashWithIndifferentAccess.new decoded
end
end
на основе включенных puts stmts я вижу, что токен декодируется в классе JWT, но он по-прежнему недоступен в контроллере:
header is eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNjZiZmQyMDAtZDExMy00NjdlLTkwMmEtMDRjMmI5YjE2ZmUwIiwiZXhwIjoxNjgwNzAyMzExfQ.x95ikz4QeWAdgm2rak_L6eUOqhILsRIepvALGieAwx8
decoding token: eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNjZiZmQyMDAtZDExMy00NjdlLTkwMmEtMDRjMmI5YjE2ZmUwIiwiZXhwIjoxNjgwNzAyMzExfQ.x95ikz4QeWAdgm2rak_L6eUOqhILsRIepvALGieAwx8
decoded is [{"user_id"=>"66bfd200-d113-467e-902a-04c2b9b16fe0", "exp"=>1680702311}, {"alg"=>"HS256"}]
decoded header is {}
JWT.decode(token, SECRET_KEY)
возвращает массив, а не хэш.
Передача массива в HashWithIndifferentAccess.new
вернет пустой хэш, который вы возвращаете контроллеру.
Просто найдите элемент массива с user_id и верните его контроллеру.
решено на основе вашего комментария. @debugger, если ты создашь ответ, я приму. Спасибо!