How to do basic authentication over HTTPs in Ruby?
I wrote a piece of code based on examples given in the Net::HTTP docs and tested it on my local WAMP server - it works fine. Here's what I have:
require 'net/http'
require 'openssl'
uri = URI('https://localhost/')
Net::HTTP.start(uri.host, uri.port,
:use_ssl => uri.scheme == 'https',
:verify_mode => OpenSSL::SSL::VERIFY_NONE) do |http|
request = Net::HTTP::Get.new uri.request_uri
request.basic_auth 'matt', 'secret'
response = http.request request # Net::HTTPResponse object
puts response
puts response.body
end
And my .htaccess
file looks like this:
AuthName "Authorization required"
AuthUserFile c:/wamp/www/ssl/.htpasswd
AuthType basic
Require valid-user
My .htpasswd
is just a one liner generated with htpasswd -c .htpasswd matt
for password "secret". When I run my code I get "200 OK" and contents of index.html. If I remove the request.basic_auth
line, I get 401 error.
UPDATE:
As indicated by @stereoscott in the comments, the :verify_mode
value I used in the example (OpenSSL::SSL::VERIFY_NONE
) is not safe for production.
All available options listed in the OpenSSL::SSL::SSLContext docs are: VERIFY_NONE, VERIFY_PEER, VERIFY_CLIENT_ONCE, VERIFY_FAIL_IF_NO_PEER_CERT, out of which (according to the OpenSSL docs) only the first two ones are used in the client mode.
So VERIFY_PEER
should be used on production, which is the default btw, so you can skip it entirely.
RUBY - SSL, Basic Auth, and POST
HTTP#post_form will execute directly, ignoring your other settings. Try this instead:
require 'net/http'
require 'uri'
url = URI.parse('https://my.url.com/path')
req = Net::HTTP::Post.new(url.path)
req.basic_auth 'user', 'pass'
req.use_ssl = true
req.form_data({'key1' => 'val1', 'key2' => 'val2'})
resp = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
puts resp
You are likely to run into trouble with the server's certificates. See my other post for instructions on how to get/configure them.
Doing a Http basic authentication in rails
Write the below code, in the controller which you want to restrict using http basic authentication
class ApplicationController < ActionController::Base
http_basic_authenticate_with :name => "user", :password => "password"
end
Making a request with open-uri would look like this:
require 'open-uri'
open("http://www.your-website.net/",
http_basic_authentication: ["user", "password"])
How to change HTTP Basic Authentication form?
Unfortunately, you cannot change the name of the fields. HTTP Basic Auth is part of the HTTP specification and therefore the functionality is hardcoded into the browsers.
Get with Basic Auth Ruby doesn't work
In the case, you can't pass form data to GET method.Look at example bellow, I wrote a piece of code based on examples given in the Net::HTTP docs and tested it on my local - it works. Here's what I have:
nfe_key = '41170608187168000160550010000001561000000053'
params = {'grupo' => 'edoc','cnpj' => '08187168000160', 'ChaveNota' => nfe_key, 'Url' => '1'}
uri = URI.parse('https://managersaashom.tecnospeed.com.br:7071/ManagerAPIWeb/nfe/imprime')
# Add params to URI
uri.query = URI.encode_www_form( params )
Net::HTTP.start(uri.host, uri.port,
:use_ssl => uri.scheme == 'https',
:verify_mode => OpenSSL::SSL::VERIFY_NONE) do |http|
request = Net::HTTP::Get.new uri.request_uri
request.basic_auth 'admin', '123mudar'
response = http.request request # Net::HTTPResponse object
puts response
puts response.body
end
Ruby Post Request with Basic Auth and Multiple Params
I've use this tool before with some success. https://jhawthorn.github.io/curl-to-ruby/
Your curl statement generates this Ruby code.
require 'net/http'
require 'uri'
uri = URI.parse("https://api.com/v1")
request = Net::HTTP::Post.new(uri)
request.basic_auth("any_string", "abc123")
request.set_form_data(
"var1" => "help",
"var2" => "me",
)
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
http.request(request)
end
# response.code
# response.body
There are about a million different HTTP request libraries in Ruby but sometimes its just simple to write it in Net HTTP (Net HTTP is included in the Ruby Standard Library).
Rails http GET request with no ssl verification and basic auth
Well, I ended up finding an answer. Maybe this will help others:
url = URI.parse('https://myaddress.com')
req = Net::HTTP::Get.new(url.path)
req.basic_auth 'user', 'pass'
sock = Net::HTTP.new(url.host, url.port)
sock.use_ssl = true
sock.verify_mode = OpenSSL::SSL::VERIFY_NONE
resp = sock.start {|http| http.request(req) }
Is there any way to encrypt the Http basic authentication password in rails?
You probably want to use environment-variables for this :)
There's a gem (Like for everything basically): https://github.com/bkeepers/dotenv
In your .env file you'd have the following:
AUTHENTICATION_USERNAME="foo"
AUTHENTICATION_PASSWORD="bar"
Where as in your controller you write it like so:
http_basic_authenticate_with name: ENV['AUTHENTICATION_USERNAME'], password: ENV['AUTHENTICATION_PASSWORD'], except: [:new, :show, :edit, :create]
This way your code is completely separated from the actual information.
Make sure to not add the .env-file to your git-repository by adding this to your gitignore:
.env
So what this does is it'll load these variables you set up in .env
into your existing environment variables. This way somebody needs to actually log into your server and get access to that particular file in order to get the username/password. And this should be more secure than having the username/password in plain text inside your controller ;)
Related Topics
Difference Between .Nil, .Blank? and .Empty
How to Get Request.Uri in Model in Rails
Creating Categories on Jekyll Driven Site
How to Read the Body Text of an Email Using Ruby's Net/Imap Library
Ruby Classes: Initialize Self VS. @Variable
How to Use Nokogiri to Parse an Xml File
Starting or Restarting Unicorn with Capistrano 3.X
How to Remove Validation Using Instance_Eval Clause in Rails
Convert JSON String to JSON Array in Rails
Calling/Applying Lambda VS. Function Call - the Syntax in Ruby Is Different. Why
Cleanest Way to Create a Hash from an Array
Code to Generate Gaussian (Normally Distributed) Random Numbers in Ruby
How to Put Assertions in Ruby Code
Using a Ruby Script to Login to a Website via Https
Accessing Ruby Class Variables with Class_Eval and Instance_Eval