ruby-on-rails - 使用 ruby​​ mechanize 在浏览器中存储登录 session cookie

标签 ruby-on-rails ruby cookies mechanize

我正在尝试登录网站并通过 Rails 操作重定向到安全页面。我的代码看起来像这样。

 def redirect_to_external 
   agent = Mechanize.new
   page = agent.get('http://example.com/home.asp')
   login_form = page.form_with(:name => "loginForm")
   login_form.login = 'username'
   login_form.password = 'password'
   agent.submit(login_form)

   #cookies = agent.cookie_jar.store.map {|i|  i} #need to store the cookie with a specific in browser
   redirect_to('http://example.com/admin.asp') #page behind password protection
 end

在后台登录成功,但实际重定向到管理页面时再次要求在浏览器中进行身份验证,因为 session cookie 未存储在浏览器中。尝试从 cookie_jar 中存储 cookie,但无法找到执行该操作的确切方法。有人可以帮助我吗?

最佳答案

这个我纠结了好久! StackOverflow 上的其他答案并没有完全解决如何缓存 cookie 和检索它们的问题,因此我将我的经验与我读过的其他答案结合到一个解决方案中。

(参见:

Rails 3 - Log into another site and keep cookie in session

Store login session cookie in browser using ruby mechanize

Get Mechanize to handle cookies from an arbitrary POST (to log into a website programmatically)

keep mechanize page over request boundaries

).

我使用此解决方案为不支持真正的 OAuth2.0 的网站创建自定义 OAuth2.0。

  1. 用户向我提供了其他站点的凭据。我在我的 session Controller 的创建方法中通过 Mechanize 将它们传递到站点并立即销毁它们(我不想尽可能多地触及其他人的安全内容。这就是为什么这一切都在 SSL 下进行的原因)。

  2. 这意味着一旦我在我的应用程序中的其他任何地方重定向,我的带有我需要的 cookie 的 Mechanize 实例就会被销毁。例如,在我的应用程序中,接下来我重定向到我的 Sessions Controllerindex 方法。如果您是 Rails 的新手,您可能会认为从 createindex 都可以使用相同的实例变量(例如带有这些 cookie 的 mechanize 代理),但这是错误的,每个重定向将摧毁一切! (基本上)

  3. 因此在重定向之前,您需要存储 cookie。在请求之间存储类似内容的唯一方法是通过缓存,而缓存不喜欢存储整个 Mechanize 实例。相反,您需要存储序列化的 cookie。唯一的麻烦是,Mechanize 没有将其 cookie 输出为字符串的方法,它只能将它们保存为文件。怎么办?

  4. StringIO 来拯救!您基本上可以使用 StringIO 伪造一个文件。说了那么多,下面是代码:

    @agent = Mechanize.new
    #handle the sign in stuff
    stringio = StringIO.new
    @agent.cookie_jar.save(stringio, session: true)
    cookies = stringio.string
    session[:login_cookies] = cookies
    

请注意,我将 session: true 传递给了 cookie_jar 的保存方法。如果没有该参数,cookie 将只保存非 session cookie。

  1. 现在我们的 session 缓存有一个字符串,其中包含来自 mechanize 的所有 cookie。要在重定向后取回它们,您将再次需要 StringIO:

    @agent = Mechanize.new
    cookies = session[:login_cookies]
    @agent.cookie_jar.load StringIO.new(cookies)
    
  2. 瞧!您的新代理已准备好像旧代理一样行事。

关于ruby-on-rails - 使用 ruby​​ mechanize 在浏览器中存储登录 session cookie,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18593380/

相关文章:

javascript - 设置cookie并显示cookie的值

ruby-on-rails - ActiveRecord:属性存在的范围

ruby-on-rails - rspec Controller 测试 : "expected #count to have changed by -1, but was changed by 0"

ruby-on-rails - gmaps4rails 信息窗口在 zurb 基础上显得扭曲

javascript - 如何拒绝Rails更新方法并触发JavaScript警报框?

ruby - 发布确认 - MQTT

ruby - RVM 与 JRuby 1.7.0 "Unknown Ruby Interpreter"

c# - 多个 cookie 选项 - ASP.NET Identity

ruby-on-rails - Rails 日志 API

javascript - 获取不发送 Cookie