Setting Request Headers in Ruby

Ruby - Send GET request with headers

Using net/http as suggested by the question.

References:

  • Net::HTTP https://ruby-doc.org/stdlib-2.4.1/libdoc/net/http/rdoc/Net/HTTP.html
  • Net::HTTP::get https://ruby-doc.org/stdlib-2.4.1/libdoc/net/http/rdoc/Net/HTTP.html#method-c-get
  • Setting headers: https://ruby-doc.org/stdlib-2.4.1/libdoc/net/http/rdoc/Net/HTTP.html#class-Net::HTTP-label-Setting+Headers
  • Net::HTTP::Get https://ruby-doc.org/stdlib-2.4.1/libdoc/net/http/rdoc/Net/HTTP/Get.html
  • Net::HTTPGenericRequest https://ruby-doc.org/stdlib-2.4.1/libdoc/net/http/rdoc/Net/HTTPGenericRequest.html and Net::HTTPHeader https://ruby-doc.org/stdlib-2.4.1/libdoc/net/http/rdoc/Net/HTTPHeader.html (for methods that you can call on Net::HTTP::Get)

So, for example:

require 'net/http'    

uri = URI("http://www.ruby-lang.org")
req = Net::HTTP::Get.new(uri)
req['some_header'] = "some_val"

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') { |http|
http.request(req)
}

puts res.body # <!DOCTYPE html> ... </html> => nil

Note: if your response has HTTP result state 301 (Moved permanently), see Ruby Net::HTTP - following 301 redirects

Setting Request Headers in Ruby

The third parameter is the headers hash.

You can do what you want by:

response = RestClient.post( 
url,
request,
:content_type => :json, :accept => :json, :'x-auth-key' => "mykey")

RSpec: setting request headers

Please try like this:

request.env['HTTP_FOO_HEADER'] = 'foo header'

Sending custom HTTP headers with Ruby

Finally figured it out. When setting up an HTTP request, using the 'https' scheme does not automatically enable TLS/SSL. You must do this explicitly before the request starts. Here's my updated version:

#!/usr/bin/env ruby -w
# frozen_string_literal: true

require 'fileutils'
require 'net/http'
require 'time'

cached_response = 'index.html' # Added
FileUtils.touch cached_response unless File.exist? cached_response # Added
uri = URI("https://www.apple.com/#{cached_response}") # Changed
file = File.stat cached_response

req = Net::HTTP::Get.new(uri)
req['If-Modified-Since'] = file.mtime.rfc2822

http = Net::HTTP.new(uri.hostname, uri.port) # Added
http.use_ssl = uri.scheme == 'https' # Added
res = http.start { |h| h.request(req) } # Changed

if res.is_a?(Net::HTTPSuccess)
File.open cached_response, 'w' do |io|
io.write res.body
end
end

How to set custom header for all requests that go through OmniAuth?

An OAuth request handler cannot force a browser (or any similar user-agent) to disclose more information than specified in the HTTP protocol. Be glad of that: any other posture could lead to information leakage.

The only connection that Omniauth might make itself is that exchanging a code for an access/refresh token. That is specific to the strategy in question, but strategies have the opportunity to include arbitrary headers in their internal client. If you're writing a custom strategy that required a basic authentication header during the access token exchange, it might look like this:

require 'omniauth-oauth2'

module OmniAuth
module Strategies
class DemoStrategy < OmniAuth::Strategies::OAuth2
option :name, "demo"
option :client_options, {
site: 'https://api.example.org',
authorize_url: 'https://auth.example.org/oauth2/authorize',
token_url: 'https://auth.example.org/oauth2/token'
}

uid { raw_info['id'].to_s }

info do
{ email: raw_info['email'], image: raw_info['avatar_url'] }
end

extra do
{ raw_info: raw_info }
end

def raw_info
@raw_info ||= access_token.get('user').parsed
end

def build_access_token
options.token_params.merge!(headers: {
'Authorization' => special_auth_header
})
super
end

def basic_auth_header
"Basic " + Base64.strict_encode64("#{options[:demo_id]}:#{options[:demo_secret]}")
end
end
end
end

Here, build_access_token is overriding the superclass's standard constructor for the internal HTTP client, and injecting extra headers before handing it back up the stack. Internally that's handed off to the oauth2 gem, which in turn uses Faraday, so it's likely anything Faraday accepts is a valid option.

If you need additional information carried to the authentication server, it may be encoded in the redirect URL by the strategy. For example, the omniauth-google-oauth2 strategy is configurable to carry authentication scopes and email hints in the URL that lands on Google's authentication endpoint.

It is also common to include a XSRF state parameter, in conjunction with an encrypted session cookie, to protect against identity spoofing. Depending on the co-operation of the authentication server, some or all of this data may be reflected in the redirection back to your handler.

At it simplest, that is handled by the authorize_params method in the strategy subclass e.g.

def authorize_params
super.tap do |params|
params[:something] = 'my_extra_value'
end
end

However, the volume of code involved in setting up extended parameters may be quite substantial in practice. For a worked example of doing this with Omniauth I'd suggest taking a looking at the source code of the Google strategy, and again I'll draw your attention to the authorize_params method which is the entry point for this heavy lifting.

In the overall flow of things, those are the touch points where server-side code can actually influence matters. There's a fundamental expectation that the user's client/browser is participating by executing nothing but normal HTTPS request.

Add headers to a request in rails

It can be set on the request object:

request = Post.new(url)
request.form_data = params
request['X-Forwarded-For'] = '203.0.113.195'
request.start(url.hostname, url.port,
:use_ssl => url.scheme == 'https' ) {|http|
http.request(request) }

See these Net::HTTP examples:

https://github.com/augustl/net-http-cheat-sheet/blob/master/headers.rb



Related Topics



Leave a reply



Submit