简体   繁体   English

使用HTTParty传递cookie

[英]Passing cookies with HTTParty

I'm trying to log in a user with HTTParty into a Rails application. 我正在尝试使用HTTParty将用户登录到Rails应用程序。 The idea is to send a POST request and get a session cookie with it, then send a GET request with this cookie and log in successfully: 这个想法是发送一个POST请求并获得一个会话cookie,然后发送一个带有该cookie的GET请求并成功登录:

POST request POST请求

HTTParty.post('url/login/', basic_auth: {user: 'user', password: 'password'}, follow_redirects: false)

returns 回报

#<HTTParty::Response:0x7f9c71bc4598 parsed_response=nil, @response=#<Net::HTTPFound 302 302 readbody=true>, @headers={"date"=>["Mon, 04 Mar 2019 08:02:26 GMT"], "server"=>["Apache"], "strict-transport-security"=>["max-age=31536000"], "set-cookie"=>["JSESSIONID=6552C1F4FD12D1C5B1D3B42168B9588A.node2; Path=/; Secure; HttpOnly"], "x-content-type-options"=>["nosniff"], "x-xss-protection"=>["1; mode=block"], "cache-control"=>["no-cache, no-store, max-age=0, must-revalidate"], "pragma"=>["no-cache"], "expires"=>["0"], "location"=>["/ipad-api/v20/login/failure/"], "vary"=>["Accept-Encoding,User-Agent"], "content-length"=>["20"], "connection"=>["close"], "content-type"=>["text/plain; charset=UTF-8"]}>

The I send a GET request 我发送一个GET请求

HTTParty.get('url/login/success/', cookie: "6552C1F4FD12D1C5B1D3B42168B9588A.node2")

and get 并得到

#<HTTParty::Response:0x7f9c71b95950 parsed_response={"head"=>{"apikey"=>nil, "sessionid"=>"320E4C622043566D5424627BDE11997D.node3", "timestamp"=>1551686567666, "sessiontimeout"=>1551689267666, "wishlistItemsCount"=>0, "basketItemsCount"=>0, "loggedIn"=>false, "role"=>"G"}, "data"=>{"user"=>{"profile"=>{"title"=>nil, "firstname"=>nil, "lastname"=>nil, "street"=>nil, "street2"=>nil, "postalcode"=>nil, "city"=>nil, "customerID"=>nil, "customerType"=>0}}, "abandonedBasket"=>false}, "messages"=>[{"code"=>"bmd.api.login.success", "statusCode"=>200, "description"=>"OK"}]}, @response=#<Net::HTTPOK 200 200 readbody=true>, @headers={"date"=>["Mon, 04 Mar 2019 08:02:47 GMT"], "server"=>["Apache"], "strict-transport-security"=>["max-age=31536000"], "set-cookie"=>["JSESSIONID=320E4C622043566D5424627BDE11997D.node3; Path=/; Secure; HttpOnly"], "x-content-type-options"=>["nosniff"], "x-xss-protection"=>["1; mode=block"], "cache-control"=>["no-cache, no-store, max-age=0, must-revalidate"], "pragma"=>["no-cache"], "expires"=>["0"], "vary"=>["Accept-Encoding,User-Agent"], "connection"=>["close"], "transfer-encoding"=>["chunked"], "content-type"=>["application/json;charset=UTF-8"]}>

Session changes and the user isn't logged in. Same requests with curl log a user in successfully. 会话更改且用户未登录。使用curl相同请求成功登录了用户。 Research showed that it might be not easy and this solution doesn't work either. 研究表明, 这可能并不容易,而且该解决方案也不起作用。

Any ideas what I'm doing wrong and in what direction to think? 有什么想法我在做错什么,以及在什么方向思考? Change to faraday, as suggested here ? 更改为法拉第,如建议在这里

To login using HTTParty you have to look more things than cookies. 要使用HTTParty登录,您必须拥有比cookie更多的东西。 You have to see CSRF_token too. 您还必须看到CSRF_token。 I think you can get authenticity_token using gsub method but I tried and it was quite difficult to create regex. 我认为您可以使用gsub方法获得authenticity_token,但我尝试过并且创建正则表达式非常困难。 So I used Nokogiri to get token which is actually present in the sign in form. 因此,我使用Nokogiri来获取令牌,该令牌实际上存在于登录表单中。 Following is details and at the end, I will put the whole code. 以下是详细信息,最后,我将介绍整个代码。

Adding required Gems, you can add it in Gemfile 添加所需的宝石,您可以将其添加到Gemfile中

gem 'httparty'
gem 'nokogiri'

Run bundle install to get gem installed. 运行bundle installbundle install gem。

To get CSRF_token we have to get sign_in page. 要获得CSRF_token,我们必须获得sign_in页面。

url = "http://localhost:3000/users/sign_in"
get_response = HTTParty.get(url)
noko_doc = Nokogiri::HTML(get_response)
auth_token = noko_doc.css('form').css('input[name="authenticity_token"]').first.values[2]

This way we got auth_token which was in the form as a hidden field. 这样,我们就获得了auth_token,它的形式是一个隐藏字段。 Now let us get cookies as session cookie may needed. 现在让我们获取cookie,因为可能需要会话cookie。

cookie_hash = HTTParty::CookieHash.new
get_response.get_fields('Set-Cookie').each { |c| cookie_hash.add_cookies(c) }

Here we are getting cookies where session is also present. 在这里,我们会在存在会话的地方获取Cookie。 Now it is time to get final params and than we will send both cookies and session to login 现在是时候获取最终参数了,然后我们将发送cookie和会话以进行登录

params = {"utf8" => "✓", "authenticity_token" => auth_token, "user[email]"=>"user@email.com",·
          "user[password]"=>"password"}

params["commit"] = "Login"

Now params are ready, you can use following httparty request to login and get cookies. 现在参数已准备就绪,您可以使用以下httparty请求登录并获取Cookie。

response = HTTParty.post("http://localhost:3000/users/sign_in", {:body=>params, headers: {'Cookie' => cookie_hash.to_cookie_string }} )

Now for other request you can run same cookies method to get all cookies back 现在,对于其他请求,您可以运行相同的cookie方法来取回所有cookie

cookie_hash = HTTParty::CookieHash.new
get_response.get_fields('Set-Cookie').each { |c| cookie_hash.add_cookies(c) }

And to access other pages you can send request with cookies as we did in above example. 如上例所示,要访问其他页面,您可以发送带有cookie的请求。 Remember if you again going to use any page which has form, again you need to get its csrf too. 请记住,如果您再次使用具有表单的任何页面,则也需要获取其csrf。

response = HTTParty.post("http://localhost:3000/users/other_urls", {headers: {'Cookie' => cookie_hash.to_cookie_string }} )

I tried this code and it is working perfectly. 我尝试了这段代码,它运行良好。 Here is complete code for your use 这是供您使用的完整代码

require 'httparty'
require 'Nokogiri'
require 'Pry'

url = "http://localhost:3000/users/sign_in"

get_response = HTTParty.get(url)
noko_doc = Nokogiri::HTML(get_response)
auth_token = noko_doc.css('form').css('input[name="authenticity_token"]').first.values[2]
cookie_hash = HTTParty::CookieHash.new
get_response.get_fields('Set-Cookie').each { |c| cookie_hash.add_cookies(c) }

params = {"utf8" => "✓", "authenticity_token" => auth_token, "user[email]"=>"user@example.com",·
          "user[password]"=>"password"}

params["commit"] = "Login"

response = HTTParty.post("http://localhost:3000/users/sign_in", {:body=>params, headers: {'Cookie' => cookie_hash.to_cookie_string }} )

puts response

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM