У меня есть следующий контроллер для моего приложения:
class Api::BaseApiController< ApplicationController
before_action :parse_request, :authenticate_member_from_token!
def index
render nothing: true, status: 200
end
protected
def authenticate_member_from_token!
if !request.headers[:escambo_token]
@member = Member.find_by_valid_token(:activate, request.headers['escambo_token'])
if !@member
render nothing: true, status: :unauthorized
end
end
end
Затем у меня есть другой контроллер, который наследуется от этого контроллера:
class Api::CategoryController < Api::BaseApiController
before_action :find_category, except: [:index]
def index
@category = Category.all
puts(@category)
render json: @category
end
Но контроллер разрешает запросы без токена.
ИЗМЕНИТЬ 1: почему-то действие index начало работать нормально. Но все еще не проверяю токен.
РЕДАКТИРОВАТЬ 2: способ фиксации с private на protected
вы уверены, что он использует правильные методы? вы можете поставить точки прерывания, чтобы гарантировать, что они будут вызваны
@maxpleaner Я снова отредактировал вопрос.
@olegario: значит, вы говорите, что он не входит в authenticate_member_from_token!? Откуда вы знаете? Входит ли в parse_request?
Если authenticate_member_from_token! не вызывается, значит, в приведенном выше коде не хватает чего-то важного. Я не вижу причин, почему бы это не называлось.
@TomLord, он вызывается, но я отправляю фальшивый токен (недействительный), и метод принимает.
@olegario Работает ли parse_request перед действием в Api::CategoryController#index?
@MartinZinovsky, да, это так.
@olegario Хорошо, но это именно то, что говорил ваш код ... Я напишу ответ, если то, что я считать вы хотите, ниже ...
@olegario А authenticate_member_from_token! работает, если в Api::CategoryController явно добавить?
@MartinZinovsky, сейчас он работает нормально, но теперь я отправляю заголовок с поддельным токеном, и метод отвечает с кодом состояния 400: request.headers['escambo_token'] = "#{@member.tokens.last.token}"
@olegario: :escambo_token != 'escambo_token', в общем. Не знаю, как headers с этим справляется.
@olegario попробуйте подход, предложенный в этот ТАК вопрос. request.headers['HTTP_ESCAMBO_TOKEN'] или request.headers['escambo-token']





Ваш код должен отображать :unauthorized, если токен отсутствует ИЛИ недействителен. Другими словами, вам нужно, чтобы код был примерно таким:
def authenticate_member_from_token!
unless Member.find_by_valid_token(:activate, request.headers['escambo_token'])
render nothing: true, status: :unauthorized
end
end
Однако с помощью этого кода вы можете столкнуться с двойным рендерингом в контроллере. Более чистый подход может заключаться в том, чтобы вместо этого вызвать исключение, затем спастись от него и соответствующим образом отобразить - например,
EscamboTokenInvalid = Class.new(StandardError)
rescue_from EscamboTokenInvalid, with: :escambo_unauthorized
def authenticate_member_from_token!
unless Member.find_by_valid_token(:activate, request.headers['escambo_token'])
raise EscamboTokenInvalid
end
end
def escambo_unauthorized
render nothing: true, status: :unauthorized
end
Здесь нет двойного рендеринга. Если before_action отображает (или перенаправляет), действие не выполняется.
Ах, достаточно честно. Причуды рельсов ..... Тем не менее, обычная практика - вызывать исключение, чтобы можно было задать индивидуальную обработку по желанию.
@SergioTulentsev уже исправлен! Спасибо.