【发布时间】:2011-11-17 09:26:16
【问题描述】:
我有一个可以进行 web api 调用的 rails 应用程序,rails 应用程序本身没有任何数据库或用户存储。每个 api 调用都需要为每个请求发送用户名和密码。
我想为 rails 应用提供一种身份验证机制。 我打算这样做:
- 显示登录页面
- 获取用户名和密码
- 存储用户名和密码
- 通过warden.authenticate 或authlogic.something 执行手动身份验证(或者甚至可能不需要,只需检查会话是否存储了某些内容)
- 然后当用户执行某项操作时,我会传递之前存储的用户名和密码。
现在我的问题是我在哪里存储密码?
如果我使用 session 我显然不能使用 cookie 存储,我可以使用 session_store = :active_record_store 但不确定它是否安全,而且我现在还没有任何数据库,为什么我应该只为 session 创建一个?
是否有任何其他机制可以在会话中存储密码? (显然是安全的方式)
早期的铁路有:
- MemoryStore
- 文件存储
但现在两者似乎都被删除了。那么还有其他解决方案吗?
答案注释:
- 存储加密密码不起作用,因为我需要在进行 api 调用时将原始密码发送到服务器。
- 我无法控制 API,因此无法更改其身份验证。
- rails 应用程序没有用户配置文件维护。一切都由 API 调用管理。
我终于想到了实现自定义内存存储,但它似乎抛出了 stackoverflow 错误。我从https://rails.lighthouseapp.com/projects/8994/tickets/1876-uninitialized-constant-actioncontrollersessionmemorystore得到代码
require 'action_dispatch'
module ActionDispatch
module Session
class CustomMemoryStore < ActionDispatch::Session::AbstractStore
GLOBAL_HASH_TABLE = {} #:nodoc:
private
def get_session(env, sid)
sid ||= generate_sid
session = GLOBAL_HASH_TABLE[sid] || {}
session = AbstractStore::SessionHash.new(self, env).merge(session)
[sid, session]
end
def set_session(env, sid, session_data)
GLOBAL_HASH_TABLE[sid] = session_data
return true
end
end
end
end
Steptools3::Application.config.session_store :custom_memory_store, :key => '_some_xyz'
【问题讨论】:
-
您可以将加密密码存储在 cookie 中,或将会话存储在服务器端的数据库中。
-
有点不清楚谁需要登录,在哪个应用程序中。 railsapp(没有分贝?)。另一个应用程序有一个 API?那 webapi 的东西在你的控制之下吗?要延迟对 API 的授权,您通常会使用 OAuth(不必保留用户/密码):让用户登录到其他应用程序,您将收到一个令牌,该令牌将授予您临时访问权限。
-
我的应用程序的用户输入用户名和密码,rails 应用程序调用 api,说“dosomething”,它调用为“user:asd, pass:qwe,task:dosomething”。因此,rails 应用程序和 api 之间没有身份验证。它只是我必须在每个请求上传递用户名和密码。
-
你能显示错误的堆栈跟踪吗?请注意,在内存中使用会话存储本质上是不可扩展的:您只能使用一个 rails 进程并且这永远不会改变(您不能在 rails 进程之间共享内存)。
-
是的,我知道这一点。它只是说
SystemStackError stack level too deep
标签: ruby-on-rails session