Vij*_*dra 9 ruby cookies ruby-on-rails 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
Run Code Online (Sandbox Code Playgroud)
登录在后台成功,但实际重定向到管理页面再次要求在浏览器中进行身份验证,因为会话cookie未存储在浏览器中.尝试存储cookie cookie_jar,但找不到确切的方法.有人可以帮助我吗?
我很长时间都在努力解决这个问题!StackOverflow上的其他答案并没有完全解决如何缓存cookie并检索它们,因此我将我的经验与我读过的其他答案结合在一起,形成一个解决方案.
(看到:
Rails 3 - 登录到另一个站点并保持cookie在会话中
使用ruby mechanize在浏览器中存储登录会话cookie
获取Mechanize来处理来自任意POST的cookie(以编程方式登录网站)
).
我使用此解决方案为不支持真正OAuth2.0的网站创建自定义OAuth2.0.
用户向我提供了其他站点的凭据.我通过Mechanize在我的Sessions控制器的create方法中将它们传递到网站上并立即销毁它们(我不想尽可能地触摸其他人的安全内容.这就是为什么这一切都在SSL下进行).
这意味着一旦我在我的应用程序中的任何其他位置重定向,我的Mechanize实例与我需要的cookie将被销毁.例如,在我的应用程序中,我接下来重定向到index我的方法Sessions Controller.如果你是新来的导轨你可能会认为同样的实例变量(如那些饼干机械化剂)是从create到index,但这是错误的,每个重定向会摧毁一切!(基本上)
因此,在重定向之前,您需要存储cookie.在请求之间存储这样的东西的唯一方法是通过缓存,缓存不喜欢存储整个机械化实例.相反,您需要存储序列化的cookie.唯一的麻烦是,Mechanize没有将cookie作为字符串输出的方法,它只能将它们保存为文件.该怎么办?
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
Run Code Online (Sandbox Code Playgroud)请注意,我传递session: true给了save方法cookie_jar.如果没有该参数,cookie将仅保存非会话cookie.
所以现在我们的会话缓存有一个字符串,其中包含来自mechanize的所有cookie.要在重定向后将它们恢复,您将再次需要StringIO:
@agent = Mechanize.new
cookies = session[:login_cookies]
@agent.cookie_jar.load StringIO.new(cookies)
Run Code Online (Sandbox Code Playgroud)瞧!您的新代理已准备好像旧代理一样行事.
请参考以下代码。这将在块中创建一个代码,以维护身份验证,
def redirect_to_external
@agent = Mechanize.new
@agent.get('http://example.com/home.asp') do | home_page | # Need to pass the others requests into the block
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
Run Code Online (Sandbox Code Playgroud)