我正在编写Sinatra Rack App,我想使用Warden进行身份验证。我正在使用heroku的工具带,所以我使用工头来运行我的应用程序。我发现some code大概应该让这个工作起来。不幸的是,当我试图实际访问Warden env对象时,它是零。
我试图使用sinatra_warden gem,但它也有own bugs(可能与此相关)。
config.ru:
require './web.rb'
use Rack::Static, :urls => ["/css", "/img", "/js"], :root => "public"
run MyApp
web.rb:
require 'sinatra'
require 'warden'
require 'data_mapper'
require './config/datamapper.rb'
require './config/warden.rb' # I've tried this inside of MyApp, still didn't work
class MyApp < Sinatra::Base
get '/test' do
env['warden'].authenticate! # env['warden'] is nil :(
end
end
配置/ warden.rb:
use Rack::Session::Cookie, :secret => ENV['SESSION_SECRET']
use Warden::Manager do |manager|
manager.default_strategies :password
manager.failure_app = MyApp.new
end
Warden::Manager.serialize_into_session { |user| user.id }
Warden::Manager.serialize_from_session { |id| User.get(id) }
Warden::Manager.before_failure do |env,opts|
# Sinatra is very sensitive to the request method
# since authentication could fail on any type of method, we need
# to set it for the failure app so it is routed to the correct block
env['REQUEST_METHOD'] = "POST"
end
Warden::Strategies.add(:password) do
def valid?
params["email"] || params["password"]
end
def authenticate!
u = User.authenticate(params["email"], params["password"])
u.nil? ? fail!("Could not log in") : success!(u)
end
end
版本:
有关如何使用Warden设置的任何想法我已经描述过?
(P.S。出于好奇,env变量究竟是什么?)
答案 0 :(得分:3)
Rack内部使用类Rack::Builder来解析你的config.ru文件并包装指令以构建中间件组件。
我相信use
中config/warden.rb
的构建者调用被忽略了。它可能会从该文件中删除指令并将它们添加到config.ru
中的中间件堆栈中:
require './web.rb'
use Rack::Session::Cookie, :secret => ENV['SESSION_SECRET']
use Warden::Manager do |manager|
manager.default_strategies :password
manager.failure_app = MyApp.new
end
use Rack::Static, :urls => ["/css", "/img", "/js"], :root => "public"
run MyApp
答案 1 :(得分:0)
在config.ru
中添加指向config / warden的链接require File.dirname(__FILE__) + '/config/warden'
阅读看守自述文件。或者在lib / warden.rb
中查看我把
Warden.test_mode!
代替/ test路径上的env调用,并在
处获得一个漂亮的空白页面http://localhost:9292/test
一些博主表示,没有很多关于监狱长的文件,但我不同意。有一个完整的维基。见https://github.com/hassox/warden/wiki
慢慢来,了解如何在Rack中使用中间件。这是一篇非常好的文章https://blog.engineyard.com/2015/understanding-rack-apps-and-middleware
我想也许你可能想开始测试,因为我找到了一个很好的例子,你可以在你的应用中使用它。
ENV['RACK_ENV'] = 'test'
require 'test/unit'
require 'rack/test'
require File.dirname(__FILE__) + '/web'
class AuthenticationTest < Test::Unit::TestCase
include Rack::Test::Methods
def app
WardenTest #MyApp
end
def test_without_authentication
get '/protected'
assert_equal 401, last_response.status
end
def test_with_bad_credentials
authorize 'bad', 'boy'
get '/protected'
assert_equal 401, last_response.status
end
def test_with_proper_credentials
authorize 'admin', 'admin'
get '/protected'
assert_equal 200, last_response.status
assert_equal "You're welcome, authenticated client", last_response.body
end
end
然后将几条路线添加到您的应用中。
helpers do
def protected!
return if authorized?
headers['WWW-Authenticate'] = 'Basic realm="Restricted Area"'
halt 401, "Not authorized\n"
end
def authorized?
@auth ||= Rack::Auth::Basic::Request.new(request.env)
@auth.provided? and @auth.basic? and @auth.credentials and
@auth.credentials == ['admin', 'admin']
end
end
get '/' do
"Everybody can see this page"
end
get '/protected' do
protected!
"You're welcome, authenticated client"
end
根据我使用Ruby的经验,开始测试任何新项目总是一个好主意。我经常先测试一些小块,但只是为了了解它们是如何工作的。
一旦你更好地了解Rack,特别是Rack :: Builder,你可以使用
map '/test' do
...all the middleware needed
run App
end
尝试不同的配置,看看哪些最适合您的需求,就像我写这篇文章时那样。
享受! ; - )