some oauth love

31
Some OAuth love <3 by Nicolas Blanco twitter.com/slainer68

Upload: nicolas-blanco

Post on 06-May-2015

12.773 views

Category:

Technology


2 download

DESCRIPTION

Some OAuth love in Ruby

TRANSCRIPT

Page 1: Some OAuth love

Some OAuth love <3by Nicolas Blanco

twitter.com/slainer68

Page 2: Some OAuth love

WHY ?THE STORY

Page 3: Some OAuth love

OAuth

• 2006 by Blaine Cook (Twitter)

• OpenID for API access

• Delegation of access

• IETF - final protocol in 2010

Page 4: Some OAuth love

OAuth

• 3-legged authentication

• Resource owner (Mme Michu)

• Server / Resource provider (vimeo)

• Client / Consumer (dvdtrololol.com)

Page 5: Some OAuth love

OAuth - Resource provider

YOU !

Page 6: Some OAuth love

OAuth - Resource owner

Page 7: Some OAuth love

OAuth - workflow

trolololdvd.com vimeo

Temporarycredentials

Redirection

Authorization page

Page 8: Some OAuth love

OAuth - Authorization page

Page 9: Some OAuth love

OAuth - WorkflowAuthorized request token

Access token

Access token

Page 10: Some OAuth love

OAuth - Signature

• Must sign all requests

• Base string

• Consumer key

• Consumer secret

• The signature

Page 11: Some OAuth love

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

Page 12: Some OAuth love

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')

Page 13: Some OAuth love

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       }

Page 14: Some OAuth love

OAuth - Faraday middleware

Page 15: Some OAuth love

OAuth2

• The next evolution : OAuth2

• Not backward-compatible

• IETF Draft

• Use it now!!!

• Facebook OpenGraph - Google - Microsoft

Page 16: Some OAuth love

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

Page 17: Some OAuth love

OAuth 2 - Debug with Curl!

curl -H "Authorization: Bearer ACCESS_TOKEN" https://gdata.youtube.com/feeds/api/users/default/uploads

Page 18: Some OAuth love

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')

Page 19: Some OAuth love

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

Page 20: Some OAuth love

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

Page 21: Some OAuth love

Omniauth - Authentication Lifecycle

• Setup phase

• Request phase

• Callback phase

Page 22: Some OAuth love

Omniauth basic strategy

module OmniAuth module Strategies class Developer include OmniAuth::Strategy

option :fields, [:name, :email] option :uid_field, :email end endend

Page 23: Some OAuth love

Omniauth base OAuth strategies

• omniauth-oauth

• omniauth-oauth2

Page 24: Some OAuth love

Write a custom OAuth2 strategy

Dailymotion ?

Page 25: Some OAuth love

Omniauth default stack

• omniauth-oauth2

• multi-json

• multi-xml

• faraday

Page 26: Some OAuth love

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

Page 27: Some OAuth love

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!

Page 28: Some OAuth love

Omniauth in RailsLier un compte uniquement (pas d’auth)

= link_to "Link to Dailymotion", "/auth/dailymotion"

match '/auth/:provider/callback', to: 'profiles#link_provider'

Page 29: Some OAuth love

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

Page 30: Some OAuth love

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

Page 31: Some OAuth love

Thank you !

Follow me : twitter.com/slainer68