【发布时间】:2015-05-23 16:35:46
【问题描述】:
为什么 Rack 中间件在与 Sinatra 应用程序中的默认 GET 和 POST 登录路由以及 401 处理结合使用时无法重定向?
相关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
查看full source code(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
存储库已准备好用于包含数据库、环境和所有内容的“克隆和架设”。登录信息;邮箱:shield@example.org,密码:shield。
问题
当访问受保护的路由 (/noway) 时,中间件会按预期注入身份验证过程。但是在认证成功后,后续重定向总是默认为root,而不是受保护页面的返回URL(/noway)。
需要解决方案
通过 Shield 成功验证后,受保护页面 (/noway) 应自动重定向到。
视觉演示
第 1 步(如下):在 Sinatra 主页上。点击链接到受保护的页面 (/noway)
第 2 步(如下):正确重定向到 /login,因为没有用户通过身份验证。正确输入正确的登录凭据。
问题行为 - 重定向到主页面而不是受保护页面
第 3A 步(如下):输入正确的登录凭据后:发送回主页面(再次)
测试登录 - 现在可以访问受保护的页面(手动,再次单击页面)
第 4 步(如下):在主页。再次单击受保护的页面 (/noway) => 授予访问权限
【问题讨论】:
标签: authentication sinatra rack middleware