Simple REST API Authentication.
Ruby 2.1+
Add this line to your application's Gemfile:
gem 'moguera-authentication'
And then execute:
$ bundle
Or install it yourself as:
$ gem install moguera-authentication
Use paramas
- access_key
- secret_access_key
- request_path
(env['REQUEST_PATH'])
- request_method
(env['REQUEST_METHOD'])
- http_date
(env['HTTP_DATE'])
- content_type
(env['CONTENT_TYPE'])
string_to_isgn = access_key + request_path + request_method + http_date + conetnt_type
signature = Baes64.encode64(OpenSSL::HMAC.hexdigest(sha1, secret_access_key, string_to_sign)
Authorization header
Authorization: MOGUERA + " " + access_key + ":" + signature
Server check
- Same request_token and server_token?
- Expired the request?
A Rack middleware inserts a Moguera Authentication.
example config.ru
require 'rack/moguera_authentication'
require 'server'
require 'json'
map '/' do
run Public
end
map '/login' do
# Add Rack::MogueraAuthentication somewhere in your rack stack
use Rack::MogueraAuthentication do |request_access_key|
# Search a secret_access_key by a request_access_key
# # example credential.json
# #=> {"user01":"secret"}
file = File.join(File.expand_path(File.dirname(__FILE__)),'credential.json')
secret_key = JSON.parse(File.open(file, &:read))[request_access_key]
unless secret_key
raise Moguera::Authentication::UserNotFound, "access_key: " + request_access_key
end
secret_key
end
run Private
end
example server.rb
require 'sinatra/base'
class Public < Sinatra::Base
post '/hello' do
[200, {"Content-Type"=>"text/plain"}, ["Hello World!"]]
end
end
class Private < Sinatra::Base
post '/hello' do
validate_user!
[200, {"Content-Type"=>"text/plain"}, ["Hello #{env['moguera.auth'].access_key}!"]]
end
private
def validate_user!
if e = env['moguera.error']
$stderr.puts e.message
case e
when Moguera::Authentication::ParameterInvalid,
Moguera::Authentication::RequestTokenRequired
halt 400, "400 Bad Request: #{e.message}\n"
when Moguera::Authentication::AuthenticationError
halt 401, "401 Unauthorized: #{e.message}\n"
when Moguera::Authentication::UserNotFound
halt 404, "404 Not Found: #{e.message}\n"
else
halt 500, "500 Internal Server Error\n"
end
end
end
end
example client-faraday.rb
require 'faraday/moguera_authentication'
url = ARGV[0]
abort "Usage: ruby #{__FILE__} http://localhost:9292/login/hello" unless url
access_key = 'user01'
secret_access_key = 'secret'
conn = Faraday.new do |faraday|
faraday.use Faraday::MogueraAuthentication, access_key, secret_access_key
faraday.response :logger
faraday.adapter Faraday.default_adapter
end
payload = '{ "key" : "value" }'
response = conn.post(url, payload, 'Content-Type' => 'application/json')
puts response.body
server
$ rackup sample/config.ru
client
$ sample/client-faraday.rb http://localhost:9292/hello
Hello World!
$ sample/client-faraday.rb http://localhost:9292/login/hello
Hello user01!
- Fork it ( https://github.com/[my-github-username]/moguera-authentication/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
Copyright (c) 2015 hiro-su.
MIT License