Manually login into website with Typheous
最近我用的是机械化,但我想用斑疹伤寒,我已经用在其他地方了。我想模仿机械化的行为,问题是我想以登录用户的身份登录到一个站点并执行请求。以下是脚本的通用版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | require 'rubygems' require 'typhoeus' GET_URL = 'http://localhost:3000' POST_URL ="http://localhost:3000/admins/sign_in" URL ="http://localhost:3000/dashboard" USERNAME_FIELD = 'admin[email]' PASSWORD_FIELD = 'admin[password]' USERNAME ="[email protected]" PASSWORD ="my_secret_password" def merge_cookies_into_cookie_jar(response) if response.headers_hash['set-cookie'].instance_of? Array response.headers_hash['set-cookie'].each do |cookie| @cookie_jar << cookie.split('; ')[0] end elsif response.headers_hash['set-cookie'].instance_of? String @cookie_jar << response.headers_hash['set-cookie'].split('; ')[0] end end # initialize cookie jar @cookie_jar = [] # for server to establish me a session response = Typhoeus::Request.get( GET_URL, :follow_location => true ) merge_cookies_into_cookie_jar(response) # like submiting a log in form response = Typhoeus::Request.post( POST_URL, :params => { USERNAME_FIELD => USERNAME, PASSWORD_FIELD => PASSWORD }, :headers => { 'Cookie' => @cookie_jar.join('; ') } ) merge_cookies_into_cookie_jar(response) # the page I'd like to get in a first place, # but not working, redirects me back to login form with 401 Unauthorized :-( response = Typhoeus::Request.get( URL, :follow_location => true, :headers => { 'Cookie' => @cookie_jar.join('; ') } ) |
cookie被发送到服务器,但出于某种原因我没有登录。我在两个不同的站点上测试了它(其中一个是我的Rails应用程序的管理)。知道我做错了什么吗,或者是更好或更广泛地适用于这个问题的解决方案?
以下是我能够成功运行的代码。
首先,您的cookie jar是一个数组,在我的代码中,它需要是一个带有替换(或哈希)的数组。当我在我的真实应用程序上运行代码时,get-url响应返回会话cookie,但post-url响应返回不同的会话cookie。
1 2 | # initialize cookie jar as a Hash @cookie_jar = {} |
调整解析,以便获得每个cookie的名称和值:
1 2 3 4 5 6 7 8 9 10 11 | def merge_cookies_into_cookie_jar(response) x = response.headers_hash['set-cookie'] case x ... when String x.split('; ').each{|cookie| key,value=cookie.split('=', 2) @cookie_jar[key]=value } end end |
。
cookie jar需要转换为字符串:
1 2 3 | def cookie_jar_to_s @cookie_jar.to_a.map{|key, val|"#{key}=#{val}"}.join(";") end |
。
最后,将您的头改为使用新的cookie jar-to-u:
1 | :headers => { 'Cookie' => cookie_jar_to_s } |
另一个好处是让cookie jar成为自己的类,可能类似于这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class CookieJar < Hash def to_s self.to_a.map{|key, val|"#{key}=#{val}"}.join(";") end def parse(*cookie_strings) cookie_strings.each{|s| s.split('; ').each{|cookie| key,value=cookie.split('=', 2) self.[key]=value } } end end |
。
我已经修复了@joelparkerhenderson的烹饪罐(因为它不在这里工作)。结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class CookieJar < Hash def to_s self.map { |key, value|"#{key}=#{value}"}.join(";") end def parse(cookie_strings) cookie_strings.each { |s| key, value = s.split('; ').first.split('=', 2) self[key] = value } self end end # Use like this: response = Typhoeus::Request.get("http://www.example.com") cookies = CookieJar.new.parse(response.headers_hash["Set-Cookie"]) Typhoeus::Request.get("http://www.example.com", headers: {Cookie: cookies.to_s}) |
您的站点是否使用了Rails伪造保护?
如果是这样,当您获得表单页面时,Rails将发送一个隐藏字段,该字段是CSRF令牌。
在HTML中,它看起来像这样:
1 | <input type="hidden" name="csrf" value="abcdef"> |
发布表单时需要使用此隐藏值:
1 | :params => {"csrf" =>"abcdef", USERNAME_FIELD => USERNAME, ... |
号
隐藏字段告诉Rails您是请求表单页面的人,因此您(并且只有您)可以发布。
以下是我关于CSRF的注释,并提供了更多信息的链接:
1 | http://sixarm.com/about/rails-session-csrf-token-jquery-ajaxprefilter.html |
相关stackoverflow csrf信息:
1 | http://stackoverflow.com/questions/941594/understand-rails-authenticity-token |
。