Prevent Back button after logout in rails - ruby-on-rails

I am tring to prevent back button after logout. So I wrote set_no_cache method in application.rb file. But it is not able to prevent back button functionality.
appliction_controller.rb :
before_filter :set_cache_buster
def set_cache_buster
response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
end
I commented the 'turbolinks' gem and removed following line from application.js :
//= require turbolinks
I am using rails 4.1.6
Any suggestions on how to fix this?
Thanks

Related

Passing cookies with HTTParty

I'm trying to log in a user with HTTParty into a Rails application.
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 request
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
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.
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. You have to see CSRF_token too. I think you can get authenticity_token using gsub method but I tried and it was quite difficult to create regex. So I used Nokogiri to get token which is actually present in the sign in form. Following is details and at the end, I will put the whole code.
Adding required Gems, you can add it in Gemfile
gem 'httparty'
gem 'nokogiri'
Run bundle install to get gem installed.
To get CSRF_token we have to get sign_in page.
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. Now let us get cookies as session cookie may needed.
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.
Now it is time to get final params and than we will send both cookies and session to login
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.
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_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. Remember if you again going to use any page which has form, again you need to get its csrf too.
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

Submitting a POST request from a rails controller

I have followed the answer of this question. And this is what i have.
def index
$response = get_insta_feed
end
def get_insta_feed
require "net/http"
require 'net/https'
require "uri"
$tag = "test"
uri = URI.parse("https://api.instagram.com/v1/tags/"+$tag+"/media/recent")
uri.query = URI.encode_www_form(parameters)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(uri.request_uri)
http.request(request).to_json
end
private
def parameters
{
"access_token" => "my access token here"
}
end
on my view page i just want to display the full json response first before parsing the data that i want to display so this:
<div>
<%=$response%>
</div>
and this is what is displayed in my div:
{"server":["nginx"],"date":["Fri, 07 Nov 2014 06:13:34 GMT"],"content-type":["text/html; charset=utf-8"],"allow":["GET"],"content-language":["en"],"expires":["Sat, 01 Jan 2000 00:00:00 GMT"],"vary":["Cookie, Accept-Language"],"pragma":["no-cache"],"cache-control":["private, no-cache, no-store, must-revalidate"],"set-cookie":["csrftoken=e70981e518d478dd7362049f9ce89cc9; expires=Fri, 06-Nov-2015 06:13:34 GMT; Max-Age=31449600; Path=/","ccode=PH; Path=/"],"connection":["close"]}
What am I doing wrong?
Please use instagram gem for the connection tasks to Instagram. For example you can use it as follows:
client = Instagram.client(:access_token => session[:access_token])
for media_item in client.tag_recent_media(tag_name)
# Use the folowing fields...
# media_item.images.thumbnail.url
# media_item.id
# media_item.likes[:count]
end
For more information of the gem, please refer to its github page.

Page isn't reloaded after clicking back button in browser

When clicking the back button in my browser, the url is changed but the page content is stale/cached.
I've tried using:
def set_no_cache
response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
end
but it doesn't seem to help.
Would be glad for any thoughts/suggestions on how to get this to work properly...

How can pass parameter with httparty gem after authentication

I am working for importing odesk API into my local project. for that i used omniauth-odesk gem for authentication and httparty gem for call http request for access odesk information.
in my Gemfile.rb
gem 'omniauth-odesk'
gem 'httparty'
in odesk_controller.rb
class OdeskController < ApplicationController
include HTTParty
def user_details
#odesk_user = env["omniauth.auth"]
end
def search_job
#response = HTTParty.get "http://www.odesk.com/api/profiles/v2/search/jobs.json", :headers=>{"Authorization"=>"Token token=\"06ede858bcdf8a5fedfa9119fd7074c4\""}
end
def check_profile
end
end
in view/odesk/search_job.html.erb
<%= #response.inspect %>
inspect information are below :
#<HTTParty::Response:0x3368f40 parsed_response={"server_time"=>1395822483, "error"=>{"status"=>400, "code"=>400, "message"=>"Malformed request: standard autorization is not supported for this API, use an application key"}}, #response=#<Net::HTTPBadRequest 400 Bad Request readbody=true>, #headers={"server"=>["nginx"], "content-type"=>["application/json"], "content-length"=>["155"], "x-odesk-error-code"=>["400"], "x-odesk-error-message"=>["Malformed request: standard autorization is not supported for this API, use an application key"], "expires"=>["Fri, 13 Oct 2000 05:00:00 GMT"], "last-modified"=>["Wed, 26 Mar 2014 08:28:03 GMT"], "cache-control"=>["no-store, no-cache, must-revalidate", "post-check=0, pre-check=0"], "pragma"=>["no-cache"], "vary"=>["Cookie,Accept-Encoding"], "date"=>["Wed, 26 Mar 2014 08:28:03 GMT"], "connection"=>["close"]}>
I am using correct api key and secret key for odesk API. and token is also correct. but where i am wrong please check and let me know.
I am following below link for making http request
http://developers.odesk.com/w/page/12364012/search%20jobs
thanks

Rails ( set_no_cache method) Cannot disable browser caching in Safari and Opera

After using Devise for my authentication, I found that there was a security hole in that, after the user logs out, the session variables are preserved. This allows anyone to press the back button and access the logged in user's previous screen.
I looked at these posts
Num 1
Num 2
Num 3
I added these lines to my application_controller
before_filter :set_no_cache
def set_no_cache
response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
end
In the _form.html.erb I added this at the top
<%if user_signed_in? %>
<%=link_to "Sign Out", destroy_user_session_path, :method => :delete %><br/>
<%= form_for(#listing) do |f| %>
<% if #listing.errors.any? %>
...........
Then I tested the application on Firefox, Chrome and Safari.
Firefox and Chrome were fine in that I logged out and hit the back button and could not see the previous screen of the user, however, in Safari and Opera, the insecure behavior persists. This code does not have an effect.
Any suggestions on how to fix this?
Thanks
I faced the same problem and found a good solution and I blogged it to
http://www.fordevs.com/2011/10/how-to-prevent-browser-from-caching-a-page-in-rails.html
To add ‘no-cache’, add the following lines # the application_controller.rb file
before_filter :set_no_cache
and the function
def set_no_cache
response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
end
First of all, for any issues with cache, use Mark Nottingham's guide on HTTP caching
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
Try this.
I found that doing this in my application controller worked great for development.
after_filter :expire_for_development
protected
def expire_for_development
expires_now if Rails.env.development?
end

Resources