Set Authorization token in rails4 header - ruby-on-rails

I cab able to handle authentication, passing params[:auth_token] through URL and get results,
like this, /event_tasks?auth_token=vDJLVv66BBg-DWWKMrF6
But instead of this i wanted to set auth_token as header and proceed,
ex: header as "Authorization: Token auth_token=vDJLVv66BBg-DWWKMrF6"
and URL as /event_tasks
How to achieve this in Rails4

For OAuth2.0, according to the specification the server should support.
Authorization: Bearer vDJLVv66Bg-DWWKMrF6

HTTP headers and CGI variables can be set directly on the #request instance variable:
#request.headers["Authorization"] = "Token token=vDJLVv66BBg-DWWKMrF6"
get :index # simulate the request with custom header
See the documentation: http://guides.rubyonrails.org/testing.html#setting-headers-and-cgi-variables

Related

Ruby on Rails how to set new params on HTTParty before redirect?

I have a POST request with HTTParty, this post validates my params and then redirect me to another page. So there are two requests.
But the second request also require params, how can I pass this params to HTTParty before the redirect?
First request:
response = HTTParty.post(URL_TO_SITE, headers: headers, body: params)
# What I need it's something like this
response.before_redirect(params: new_params)
I don't know if this is the correct way, so how can I do that?
Disable follow redirect (as described here: https://github.com/jnunemaker/httparty/issues/380)
Load initial request
Save cookies
Do manual redirect with the cookies

HTTP Token: Access denied

i m getting message "**HTTP Token: Access denied**" when access via browser http://localhost:3000/api/v1/tasks.json?auth_token=szVkqLnUbdzbekV8B-n_
but when i access from terminal that's working on success curl http://localhost:3000/api/v1/moments.json -H 'Authorization: Token token="szVkqLnUbdzbekV8B-n_"'
here code
class Api::V1::TaskController < ApplicationController
before_action :autentifikasi
def index
#tasks = current_user.tasks
end
private
def autentifikasi
authenticate_or_request_with_http_token('Premium') do |token, options|
#current_user = User.find_by(authentication_token: token)
end
end
end
end
anybody help me please !! what's wrong with my code ?
There is nothing wrong with you code - the error is in your testing methodology.
The cURL example properly sends a Authorization: Token header and sends the token along as well.
Requesting http://localhost:3000/api/v1/tasks.json?auth_token=szVkqLnUbdzbekV8B-n_ in a browser would simply set params['auth_token'] as it is a query parameter. Which will of course cause the authentication to fail.
Rails and most sane frameworks do not treat HTTP headers and query parameters as equivalent. That would leave your app looking like swiss cheese.
If you want to test token based auth via a browser you should use a plugin such as Postman which allows you to setup the request headers. Better yet is to write an actual automated integration test.
A Guide to Testing Rails Applications
RSpec Rails: Request spec
Postman
It is because authenticate_or_request_with_http_token expects an Authorization: Token from in a request header.
You are setting the header in the cURL command while in browser you are passing it as a query parameter.
So there is no token in the Request Header so your method is unable to find the token when accessed via a browser.

Receiving a request with no accessible data. ActionDispatcher, therefore, extracts no usable params

I'm getting a CORS POST request via OPTIONS sent to my app. It has no content-type set for the request.
It successfully gets to the right Controller action, but there is no accessible data. If I type params, there is nothing I can touch.
I did, however, discover that if I created Rack Middleware, and read the env['rack.input'], I could find all the data in the request I was looking for. So I wrote this :
env['CONTENT_TYPE'] = 'application/js'
rack_input = env['rack.input'].read
params = CGI::parse(rack_input).to_json
env['rack.input'] = StringIO.new params
env['rack.input'].rewind
status, headers, response = #app.call env
And magically, now in my controller, I can type params and see that ActionDispatcher successfully extracted the key/values from the request and make them accessible in my controller.
There's something suspicious about this. Is there are more appropriate way to extract OPTIONS requests and their respective data?
The OPTIONS call should not deal with data at all. It's a preflighted request to determine which actions are allowed using when using CORS.
RFC:
http://greenbytes.de/tech/webdav/rfc2616.html#rfc.section.14.7
The call will return with the allowed CORS HTTP verbs and a POST request should follow right after if POSTs are allowed on the server.

Reading header data in Ruby on Rails

I am making an API where in the access token for Facebook login will be sent in through header data.
How do I read this data from the header?
request.headers["Content-Type"] # => "text/plain"
replace "Content-Type" with the name of the header that you want to read.
Update for Rails 4.2
There are 2 ways to get them in Rails 4.2:
Old way (still working):
request.headers["Cookie"]
New way:
request.headers["HTTP_COOKIE"]
To get a Hash with all headers of the request.
request.headers
Rails now attaches HTTP_ to the header as well as converting it to all caps so it would now be:
request.headers["HTTP_CONTENT_TYPE"]
To get hash of actual http headers use #_headers in controller.

Sending POST requests from Rails controller for authentication

I am quite new to Ruby and RoR, and have been struggling with a problem and am not getting anywhere.
Basically I am building a "proxy" webservice that will handle certain requests, passing them to a third party website. The response received from the third party website is in HTML, which will then be parsed and an appropriate XML response will be given.
I'm at a point where I need to send POST requests via my controller in Rails to authenticate a user, which I'm doing using this code:
require "net/http"
require "uri"
uri = URI.parse("http://myurl.com/members.cgi")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data({"email_login" => "user#email.com", "password_login" => "password"})
response = http.request(request)
My problem lies on the response I am receiving. This specific POST request, when successful (i.e. user has successfully authenticated), is returning a 302 redirect. That in itself is not an issue, as I can follow the redirect by getting the 'location' header value:
redirectLocation = response['location']
Where I'm getting stuck is in keeping myself authenticated when following the redirect with the following line:
redirectResponse = Net::HTTP.get_response(URI.parse(redirectLocation))
This follows the redirect but return a response showing I am not authenticated??
I don't really understanding why this is happening. I can see there is an authentication cookie being returned with my original response by reading:
response['cookie']
So finally my question is what do I need to do to get the server to recognise my authentication status? Pass the cookie with my second request somehow? If so, how do I do it?
Many thanks in advance for your time!
Rog
Yes you need to set the cookie. I think it probably give you some kind of a session id. Which you need to pass with every request.
look at this code snippet for a example on how to pass on a cookie that you get as a response with your new requests.

Resources