Date post: | 06-May-2015 |
Category: |
Technology |
Upload: | nicolas-blanco |
View: | 12,773 times |
Download: | 2 times |
Some OAuth love <3by Nicolas Blanco
twitter.com/slainer68
WHY ?THE STORY
OAuth
• 2006 by Blaine Cook (Twitter)
• OpenID for API access
• Delegation of access
• IETF - final protocol in 2010
OAuth
• 3-legged authentication
• Resource owner (Mme Michu)
• Server / Resource provider (vimeo)
• Client / Consumer (dvdtrololol.com)
OAuth - Resource provider
YOU !
OAuth - Resource owner
OAuth - workflow
trolololdvd.com vimeo
Temporarycredentials
Redirection
Authorization page
OAuth - Authorization page
OAuth - WorkflowAuthorized request token
Access token
Access token
OAuth - Signature
• Must sign all requests
• Base string
• Consumer key
• Consumer secret
• The signature
OAuth - Base stringThe HTTP Method is GETThe URL is http://vimeo.com/api/rest/v2/The method is vimeo.people.getInfoThere is only one API parameter for vimeo.people.getInfo: user_id is bradThe oauth_consumer_key is abcdef0123456The oauth_nonce is r4nd0m1234The oauth_timestamp is 1328533189The oauth_signature_method is HMACThe oauth_version is 1.0
GET&http%3A%2F%2Fvimeo.com%2Fapi%2Frest%2Fv2%2F&method%3Dvimeo.people.getInfo%26oauth_consumer_key%3Dabcdef0123456%26oauth_nonce
%3Dr4nd0m1234%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1328533189%26oauth_version%3D1.0%26user_id%3Dbrad
OAuth - Ruby
• At least some Ruby!
• ruby gem install oauth
@callback_url = "http://www.dvdtrololol.com/oauth/callback"
@consumer = OAuth::Consumer.new("key","secret", :site => "https://vimeo.com/auth")
@request_token = @consumer.get_request_token(:oauth_callback => @callback_url)session[:request_token] = @request_tokenredirect_to @request_token.authorize_url(:oauth_callback => @callback_url)
@access_token = @request_token.get_access_token@videos = @access_token.get('/videos.json')
OAuth - signature
• Here comes Faraday ! Middleware like Rack
• https://github.com/technoweenie/faraday
builder.use Faraday::Request::OAuth, { :consumer_key => @consumer_key, :consumer_secret => @consumer_secret, :token => @atoken, :token_secret => @asecret }
OAuth - Faraday middleware
OAuth2
• The next evolution : OAuth2
• Not backward-compatible
• IETF Draft
• Use it now!!!
• Facebook OpenGraph - Google - Microsoft
Why <3 OAuth2
• Clients don’t need cryptography anymore (HTTPS)
• Less complicated signatures
• Better support for non-browser apps
• Access tokens are short-lived
• Clean separation between auth server and request server
OAuth 2 - Debug with Curl!
curl -H "Authorization: Bearer ACCESS_TOKEN" https://gdata.youtube.com/feeds/api/users/default/uploads
OAuth2 - Gem
client = OAuth2::Client.new('client_id', 'client_secret', :site => 'https://www.youtube.com/auth')
client.auth_code.authorize_url(:redirect_uri => 'http://www.dvdtrololol.com/oauth2/callback')
# => "https://example.org/oauth/authorization?response_type=code&client_id=client_id&redirect_uri=http://localhost:8080/oauth2/callback"
token = client.auth_code.get_token('authorization_code_value', :redirect_uri => 'http://www.dvdtrololol.com/oauth2/callback')
videos = token.get('/videos.json')
OAuth2 - Faraday middleware
module Faraday class Request::OAuth2 < Faraday::Middleware def call(env) env[:request_headers]['Authorization'] = "Bearer #{@access_token.token}"
@app.call(env) end
def initialize(app, access_token) @app, @access_token = app, access_token end endend
Omniauth love <3• Rack standardized multi-provider
authentication
• Very flexible
Rails.application.config.middleware.use OmniAuth::Builder do provider :developer unless Rails.env.production? provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']end
Omniauth - Authentication Lifecycle
• Setup phase
• Request phase
• Callback phase
Omniauth basic strategy
module OmniAuth module Strategies class Developer include OmniAuth::Strategy
option :fields, [:name, :email] option :uid_field, :email end endend
Omniauth base OAuth strategies
• omniauth-oauth
• omniauth-oauth2
Write a custom OAuth2 strategy
Dailymotion ?
Omniauth default stack
• omniauth-oauth2
• multi-json
• multi-xml
• faraday
require 'omniauth/strategies/oauth2'
module OmniAuth module Strategies class Dailymotion < OmniAuth::Strategies::OAuth2 DEFAULT_SCOPE = 'email userinfo' option :name, "dailymotion" option :client_options, { :site => 'https://api.dailymotion.com', :authorize_url => '/oauth/authorize', :token_url => '/oauth/token' }
# ...
Omniauth custom OAuth2 strategy
Omniauth custom OAuth2 strategy
uid { raw_info['id'] } info do prune!({ 'screenname' => raw_info['screenname'], 'url' => raw_info['url'], 'email' => raw_info['email'], 'fullname' => raw_info['fullname'], 'description' => raw_info['description'], 'gender' => raw_info['gender'] }) end def raw_info @raw_info ||= access_token.get('/me', :params => { :fields => %w(id,url,email,fullname,description,gender).join(",") }).parsed end
Give more info for free!
Omniauth in RailsLier un compte uniquement (pas d’auth)
= link_to "Link to Dailymotion", "/auth/dailymotion"
match '/auth/:provider/callback', to: 'profiles#link_provider'
class ProfilesController < AuthenticatedController def show end
def link_provider current_user.update_attributes_for_provider(params[:provider], auth_hash.credentials)
redirect_to profile_path, notice: "Successfully linked to provider" end
protected def auth_hash request.env['omniauth.auth'] endend
class User # ... def update_attributes_for_provider(provider, credentials) credentials.each do |key, val| send("#{provider}_#{key}=", val) if respond_to?("#{provider}_#{key}=") end
save endend
Omniauth in Rails - Authentication with Devise
class Users::OmniauthCallbacksController < ApplicationController def create @user = User.find_or_create_for_provider(params[:provider], auth_hash) sign_in_and_redirect(@user, :event => :authentication) endend
Thank you !
Follow me : twitter.com/slainer68