How to simply roll your own OAuth2 provider with direct user/pass access
For one of our clients, we are building an interface application and an API layer. All authentication and stuff is going to happen in the API and our interface will use OAuth to authenticate with the API.
Initially, we won't want any interface code in the API application so I was looking for a solution where we could directly pass the username and password from a login form in the interface to our API OAuth Provider.
Since we are writing both apps we don't have a need to have the user accept it's app access. Here's the code in the controller:
app/controllers/authorize_controller.rb
class AuthorizeController < ApplicationController
skip_before_filter :verify_authenticity_token
def sign_in
u = User.find_by_username(params[:username])
Songkick::OAuth2::Provider.handle_passwords do |client, username, password, scopes|
user = User.find_by_username!(username)
if user.authenticate?(password)
user.grant_access!(client)
else
nil
end
end
oauth = Songkick::OAuth2::Provider.parse(nil, env)
response.headers = oauth.response_headers
if body = oauth.response_body
render :text => body, :status => oauth.response_status
end
end
end
Here are the routes:
config/routes.rb
OauthProvider::Application.routes.draw do
post "/oauth/token" => "authorize#sign_in"
end
I am using the <a href="songkick-oauth2-provider">https://github.com/songkick/oauth2-provider</a>. If you want to know how to set up your models, please read their README.
I built a little Rake task to test a connection by trying to grab an access token from the provider.
lib/tasks/oauth_test.rake
require 'oauth2'
namespace :oauth do
desc "Test our oauth connection"
task :test => :environment do
client = OAuth2::Client.new(
"h171cbibzlqfzkdojeqpwbjzt235xw5",
"4vs772iob20vtvtaxgy6ndnpauv2sj",
:site => "http://oauthprovider.dev")
token = client.password.get_token("michiel", "password")
puts token.inspect
end
end
All works fine!
If you have questions about the details. Please hook me up at <a href="http://twitter.com/michiels">@michiels</a> or <a href="mailto:michiel@firmhouse.com">michiel@firmhouse.com</a>!