我正在尝试登录网站并从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,但找不到确切的方法。有人可以帮助我吗?
答案 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。
用户向我提供了其他网站的凭据。我通过Mechanize在我的Sessions控制器的create方法中将它们传递到网站上并立即销毁它们(我不想尽可能地触摸其他人的安全内容。这就是为什么这一切都在SSL下进行)。
这意味着一旦我在我的应用程序中的任何其他位置重定向,我的Mechanize实例与我需要的cookie将被销毁。例如,在我的应用中,我接下来重定向到index
的{{1}}方法。如果您是rails的新手,您可能会认为Sessions Controller
到create
可以使用相同的实例变量(例如带有这些cookie的机械化代理),但这是错误的,每次重定向都会破坏所有内容! (基本上)
因此,在重定向之前,您需要存储Cookie。在请求之间存储这样的东西的唯一方法是通过缓存,缓存不喜欢存储整个机械化实例。相反,您需要存储序列化的cookie。唯一的麻烦是,Mechanize没有将cookie作为字符串输出的方法,它只能将它们保存为文件。该怎么办?
StringIO救援!您实际上可以使用StringIO伪造文件。在谈完之后,这是代码:
index
请注意,我已将@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。
所以现在我们的会话缓存有一个字符串,其中包含来自mechanize的所有cookie。要在重定向后让他们回来,你需要再次使用StringIO:
cookie_jar
瞧!您的新代理人已准备好像旧代理一样行事。
答案 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