使用ruby mechanize在浏览器中存储登录会话cookie

时间:2013-09-03 13:17:26

标签: 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

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

2 个答案:

答案 0 :(得分:7)

我很长时间都在努力解决这个问题! 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. 用户向我提供了其他网站的凭据。我通过Mechanize在我的Sessions控制器的create方法中将它们传递到网站上并立即销毁它们(我不想尽可能地触摸其他人的安全内容。这就是为什么这一切都在SSL下进行)。

  2. 这意味着一旦我在我的应用程序中的任何其他位置重定向,我的Mechanize实例与我需要的cookie将被销毁。例如,在我的应用中,我接下来重定向到index的{​​{1}}方法。如果您是rails的新手,您可能会认为Sessions Controllercreate可以使用相同的实例变量(例如带有这些cookie的机械化代理),但这是错误的,每次重定向都会破坏所有内容! (基本上)

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

  4. StringIO救援!您实际上可以使用StringIO伪造文件。在谈完之后,这是代码:

    index
  5. 请注意,我已将@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将只保存非会话cookie。

    1. 所以现在我们的会话缓存有一个字符串,其中包含来自mechanize的所有cookie。要在重定向后让他们回来,你需要再次使用StringIO:

      cookie_jar
    2. 瞧!您的新代理人已准备好像旧代理一样行事。

答案 1 :(得分:1)

请参考以下代码。这将在块中创建一个代码,这将保持身份验证,

 def redirect_to_external 
    @agent = Mechanize.new
    @agent.get('http://example.com/home.asp') do | home_page |
    login_form = home_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
    @agent.get('http://example.com/admin.asp') #page behind password protection
   end  
end