Защо мидълуерът на Rack не успява да пренасочи, когато е съчетан с маршрутите за влизане по подразбиране GET и POST и обработката на 401 в приложението Sinatra?
Съответен екстракт от мидълуер на Shield:
module Shield
class Middleware
attr :url
def initialize(app, url = "/login")
@app = app
@url = url
end
def call(env)
tuple = @app.call(env)
if tuple[0] == 401
[302, headers(env["SCRIPT_NAME"] + env["PATH_INFO"]), []]
else
tuple
end
end
private
def headers(path)
{ "Location" => "%s?return=%s" % [url, encode(path)],
"Content-Type" => "text/html",
"Content-Length" => "0"
}
end
def encode(str)
URI.encode_www_form_component(str)
end
end
end
Вижте пълния изходен код (104 реда/2,8kb).
Ето подходящ извлечение от приложението Sinatra:
# application_controller.rb
class ApplicationController < Sinatra::Base
helpers Shield::Helpers
use Shield::Middleware, "/login"
...
get '/noway' do
error(401) unless authenticated(User)
erb :app_noway
end
get '/login' do
erb :login
end
post "/login" do
if login(User, params[:login], params[:password])
remember(authenticated(User)) if params[:remember_me]
redirect(params[:return] || "/")
else
redirect "/login"
end
end
end
Пълен изходен код (основно приложение, показващо проблемното поведение), за лесно и незабавно разглеждане: https://github.com/shieldtest/shieldtest
Хранилището е готово за „клониране и събиране“ с база данни, env и всичко останало. Идентификационни данни за вход; имейл: [email protected], парола: shield.
Проблем
При достъп до защитен маршрут (/noway), междинният софтуер инжектира процес на удостоверяване, както е предвидено. Но след успешното удостоверяване, последващото пренасочване винаги се задава по подразбиране на root, вместо URL адреса за връщане за защитената страница (/noway).
Необходимо решение
Защитената страница (/noway) трябва да бъде пренасочена автоматично след успешно удостоверяване чрез Shield.
Визуална разходка
Стъпка 1 (по-долу): На главната страница на Синатра. Щракнете върху връзка към защитена страница (/noway)
Стъпка 2 (по-долу): Правилно пренасочен към /login, тъй като нито един потребител не е удостоверен. Въведете правилно правилните идентификационни данни за вход.
ПРОБЛЕМНО ПОВЕДЕНИЕ - пренасочено към главната вместо към защитената страница
Стъпка 3A (по-долу): След въвеждане на правилни идентификационни данни за вход: изпратено обратно към главната страница (отново)
ТЕСТВАНЕ НА ВХОД - защитената страница е достъпна сега (ръчно, чрез повторно щракване върху страницата)
Стъпка 4 (по-долу): На главната страница. Щракнете отново върху защитената страница (/noway) => Достъпът е предоставен