虽然Rails在Web方面提供的功能非常强大
但是在某一些应用场景下,他的性能确是一个致命伤
这时我们可以用到ruby的一个高性能的框架Goliath
这里就涉及到在Goliath中需要读取Rails Session的信息,来判断用户是否已经登录,这样才是符合我的需要的。
于是研究了一下ActionDispatch中cookie和session的代码以后,确信这是完全可行的
注意:前提条件是Rails的session选用的是cookie_store(其它的没有深入研究)
最终成功的代码如下:
require "goliath"
require "yaml"
require 'action_pack'
require 'action_dispatch'
require "json"
#这个类就是我们解析Session数据的一个Rack MiddleWare
class RailsSessionDecryptor
def initialize(app)
@app = app
end
def call(env)
env["action_dispatch.secret_key_base"] = "b1fff344cb743e7d6e84a2d9531e70c54500dfe7a0279d0a33547fa8c2e9d0a752842133f46169547872c37f125dd797bd432cc6bbabfc85d565cebf513d2807" #这里的值是rails/config/secrets.yml中的secret_key_base的值
env["action_dispatch.encrypted_signed_cookie_salt"] = "signed encrypted cookie"
env["action_dispatch.encrypted_cookie_salt"] = "encrypted cookie"
env["action_dispatch.cookies_serializer"] = :json
env["action_dispatch.key_generator"] = ActiveSupport::KeyGenerator.new(env["action_dispatch.secret_key_base"], iterations: 1000)
env["rails_session"] = rails_cookies(env).encrypted["_lets_talk_session"]#这里的值是rails/config/initializers/session_store.rb中的:key的值
@app.call(env)
end
def rails_cookies(env)
env['action_dispatch.cookies'] ||= ActionDispatch::Cookies::CookieJar.build(ActionDispatch::Request.new(env))
end
end
class Inbox < Goliath::API
use RailsSessionDecryptor
def response(env)
return ["401" , {} , {"status" => "fail"}] unless user_id
[200 , {} , session.inspect]
end
private
def session
env["rails_session"]
end
def user_id
session["user_id"]
end
end