devise tutorial - 2011 rubyconf taiwan

70
BUILD YOUR AUTHENTICATION SYSTEM WITH DEVISE Tse-Ching Ho (何澤清) 2011-08-26

Upload: tse-ching-ho

Post on 06-May-2015

2.598 views

Category:

Technology


5 download

DESCRIPTION

[Tutorial] Build your authentication system with Devise

TRANSCRIPT

Page 1: devise tutorial - 2011 rubyconf taiwan

BUILD YOUR AUTHENTICATION SYSTEM

WITH DEVISETse-Ching Ho (何澤清)

2011-08-26

Page 2: devise tutorial - 2011 rubyconf taiwan

HTTPS://GITHUB.COM/TSECHINGHO/DEVISE_TUTORIAL

git clone git://github.com/tsechingho/devise_tutorial.git

Page 3: devise tutorial - 2011 rubyconf taiwan

•OminiAuth Client Applicationproviders: Facebook, Twitter, Github

•OpenID Client Applicationproviders: Google, Yahoo, Google Apps

• LDAP Client Applicationproviders: Localhost OpenLDAP

• CAS Client Applicationproviders: Localhost CAS

AGENDA

Page 4: devise tutorial - 2011 rubyconf taiwan

WHAT IS AUTHENTICATION ?

Page 5: devise tutorial - 2011 rubyconf taiwan

ABOUT AUTHENTICATION

• authentication and authorization are two things

• authentication is just an identity token / ticket

• can use multi authentication providers on one site

• one user can have many authentications

Page 6: devise tutorial - 2011 rubyconf taiwan

CAS server

devise

omniauth

OpenID providers

Oauth providers

LDAP providers

3rd partyproviders

username /password

customer

DEVISE - OMNIAUTH WAY

Page 7: devise tutorial - 2011 rubyconf taiwan

WHAT DO WE NEED ?

Page 8: devise tutorial - 2011 rubyconf taiwan

USER STORY PLEASE

Page 9: devise tutorial - 2011 rubyconf taiwan

updated_at datetime

string

created_at

id

datetime

last_sign_in_ip

integer

last_sign_in_at

remember_created_at

email

string

datetime

sign_in_count

datetime

string

encrypted_password

datetimereset_password_sent_at

string

current_sign_in_at

datetime

string

integer

reset_password_token

current_sign_in_ip

Model: Managerhas_many :authentications, :as => :resource

has_one :profile, :as => :resource

managers

datetimeupdated_at

created_at datetime

nickname string

fullname string

last_name string

first_name string

resource_type string

resource_id integer

id integer

Model: Profilebelongs_to :resource, :polymorphic => true

profiles

updated_at datetime

datetimecreated_at

umail string

uname string

stringuid

provider string

resource_type string

resource_id integer

id integer

Model: Authenticationbelongs_to :resource, :polymorphic => true

authentications

updated_at datetime

string

created_at

id

datetime

last_sign_in_ip

integer

last_sign_in_at

remember_created_at

email

string

datetime

sign_in_count

datetime

string

encrypted_password

datetimereset_password_sent_at

string

current_sign_in_at

datetime

string

integer

reset_password_token

current_sign_in_ip

Model: Userhas_many :authentications, :as => :resource

has_one :profile, :as => :resource

users

POSSIBLE DB SCHEMA

Page 10: devise tutorial - 2011 rubyconf taiwan

WHY DEVISE ?

Page 11: devise tutorial - 2011 rubyconf taiwan

FEATURES OF DEVISE

• rack - simple and fast

• strategies - logical and flexible

•modularity - maintainable rails engine

•multi-models - signed in at the same time

• extensions - diversity

• authentication scheme with general user’s needs

Page 12: devise tutorial - 2011 rubyconf taiwan

•Database authenticatable

• Token authenticatable

•Omniauthable

• Confirmable

• Recoverable

• Registerable

• Rememberable

• Trackable

• Timeoutable

• Validatable

• Lockable

• Encryptalbe

BUILDED IN MODULES

Page 13: devise tutorial - 2011 rubyconf taiwan

EXTENSION MODULES

•ORM

• Encryption

• Authentication

• UI enhancement

• https://github.com/plataformatec/devise/wiki/Extensions

Page 14: devise tutorial - 2011 rubyconf taiwan

FILTERS & HELPERS

• authenticate_user!

• user_signed_in?

• current_user

• user_session

• user_root_path

Page 15: devise tutorial - 2011 rubyconf taiwan

DEMO

SHOW, DON’T TELL

Page 16: devise tutorial - 2011 rubyconf taiwan

GIT LOGS ARE FRIENDS

Page 17: devise tutorial - 2011 rubyconf taiwan

• rails new devise_tutorial -JTd mysql• cd devise_tutorial• vim Gemfile• bundle install• rails generate scaffold page title:string content:text• rake db:create• rake db:migrate• rails server

bundle exec unicorn -p 3000• tail -f log/development.log

NEW RAILS APP

Page 18: devise tutorial - 2011 rubyconf taiwan

GIT CHECKOUT HEROKU

Page 19: devise tutorial - 2011 rubyconf taiwan

• git checkout heroku

• heroku keys:add

• heroku create

• git push heroku master

• heroku rake db:setup

• heroku open

DEPLOY TO HEROKU

Page 20: devise tutorial - 2011 rubyconf taiwan

GIT CHECKOUT USER

Page 21: devise tutorial - 2011 rubyconf taiwan

DEVISE CUSTOMIZATION

• config - set configurations for devise

•migrations - set database fields

•models - select modules, set attributes

• routes - set uri mapping

• controllers - set filters and redirects

• views - set html and css

Page 22: devise tutorial - 2011 rubyconf taiwan

rake middlewareuse ActionDispatch::Staticuse Rack::Lockuse ActiveSupport::Cache::Strategy::LocalCacheuse Rack::Runtimeuse Rails::Rack::Loggeruse ActionDispatch::ShowExceptionsuse ActionDispatch::RemoteIpuse Rack::Sendfileuse ActionDispatch::Callbacksuse ActiveRecord::ConnectionAdapters::ConnectionManagementuse ActiveRecord::QueryCacheuse ActionDispatch::Cookiesuse ActionDispatch::Session::CookieStoreuse ActionDispatch::Flashuse ActionDispatch::ParamsParseruse Rack::MethodOverrideuse ActionDispatch::Headuse ActionDispatch::BestStandardsSupportuse Warden::Managerrun DeviseTutorial::Application.routes

Page 23: devise tutorial - 2011 rubyconf taiwan

GIT CHECKOUT MANAGER

Page 24: devise tutorial - 2011 rubyconf taiwan

rake routes manager_root GET /pages/:id(.:format) {:controller=>"pages", :id=>"management", :action=>"show"} new_manager_session GET /managers/sign_in(.:format) {:controller=>"devise/sessions", :action=>"new"} manager_session POST /managers/sign_in(.:format) {:controller=>"devise/sessions", :action=>"create"} destroy_manager_session DELETE /managers/sign_out(.:format) {:controller=>"devise/sessions", :action=>"destroy"} manager_password POST /managers/password(.:format) {:controller=>"devise/passwords", :action=>"create"} new_manager_password GET /managers/password/new(.:format) {:controller=>"devise/passwords", :action=>"new"} edit_manager_password GET /managers/password/edit(.:format) {:controller=>"devise/passwords", :action=>"edit"} PUT /managers/password(.:format) {:controller=>"devise/passwords", :action=>"update"}cancel_manager_registration GET /managers/cancel(.:format) {:controller=>"devise/registrations", :action=>"cancel"} manager_registration POST /managers(.:format) {:controller=>"devise/registrations", :action=>"create"} new_manager_registration GET /managers/sign_up(.:format) {:controller=>"devise/registrations", :action=>"new"} edit_manager_registration GET /managers/edit(.:format) {:controller=>"devise/registrations", :action=>"edit"} PUT /managers(.:format) {:controller=>"devise/registrations", :action=>"update"} DELETE /managers(.:format) {:controller=>"devise/registrations", :action=>"destroy"} user_root GET /pages/:id(.:format) {:controller=>"pages", :id=>"dashboard", :action=>"show"} new_user_session GET /users/sign_in(.:format) {:controller=>"devise/sessions", :action=>"new"} user_session POST /users/sign_in(.:format) {:controller=>"devise/sessions", :action=>"create"} destroy_user_session DELETE /users/sign_out(.:format) {:controller=>"devise/sessions", :action=>"destroy"} user_password POST /users/password(.:format) {:controller=>"devise/passwords", :action=>"create"} new_user_password GET /users/password/new(.:format) {:controller=>"devise/passwords", :action=>"new"} edit_user_password GET /users/password/edit(.:format) {:controller=>"devise/passwords", :action=>"edit"} PUT /users/password(.:format) {:controller=>"devise/passwords", :action=>"update"} cancel_user_registration GET /users/cancel(.:format) {:controller=>"devise/registrations", :action=>"cancel"} user_registration POST /users(.:format) {:controller=>"devise/registrations", :action=>"create"} new_user_registration GET /users/sign_up(.:format) {:controller=>"devise/registrations", :action=>"new"} edit_user_registration GET /users/edit(.:format) {:controller=>"devise/registrations", :action=>"edit"} PUT /users(.:format) {:controller=>"devise/registrations", :action=>"update"} DELETE /users(.:format) {:controller=>"devise/registrations", :action=>"destroy"} root /(.:format) {:controller=>"pages", :action=>"show"}

Page 25: devise tutorial - 2011 rubyconf taiwan

GIT CHECKOUT PROVIDER

Page 26: devise tutorial - 2011 rubyconf taiwan

updated_at datetime

string

created_at

id

datetime

last_sign_in_ip

integer

last_sign_in_at

remember_created_at

email

string

datetime

sign_in_count

datetime

string

encrypted_password

datetimereset_password_sent_at

string

current_sign_in_at

datetime

string

integer

reset_password_token

current_sign_in_ip

Model: Userhas_many :authentications, :as => :resource

has_one :profile, :as => :resource

users

updated_at datetime

datetimecreated_at

umail string

uname string

stringuid

provider string

resource_type string

resource_id integer

id integer

Model: Authenticationbelongs_to :resource, :polymorphic => true

authentications

PROVIDER - USER DB SCHEMA

Page 27: devise tutorial - 2011 rubyconf taiwan

GIT CHECKOUT OA-OAUTH

Page 28: devise tutorial - 2011 rubyconf taiwan

rake middlewareuse ActionDispatch::Static......use ActionDispatch::BestStandardsSupportuse Warden::Manageruse OmniAuth::Strategies::Facebookuse OmniAuth::Strategies::Twitteruse OmniAuth::Strategies::GitHubuse OmniAuth::Strategies::OpenIDuse OmniAuth::Strategies::OpenIDuse OmniAuth::Strategies::OpenIDuse OmniAuth::Strategies::GoogleAppsuse OmniAuth::Strategies::GoogleAppsrun DeviseTutorial::Application.routes

OMNIAUTH MIDDLEWARES

Page 29: devise tutorial - 2011 rubyconf taiwan

DEVISE OMNIAUTH ROUTES

• /users/auth/:provider(.:format) { :controller => "users/omniauth_callbacks", :action => "passthru" }

• user_omniauth_callback/users/auth/:action/callback(.:format) { :controller => "users/omniauth_callbacks", :action => /facebook|twitter|github/ }

Page 30: devise tutorial - 2011 rubyconf taiwan

NEEDS OF OAUTH

• create new app record for each client site

• app id and app secret are required

• callback url must match

• access token / error message will append to callback url

• specific yaml pattern for user auth data

Page 31: devise tutorial - 2011 rubyconf taiwan

---provider: facebookuid: "1290347368"credentials: token: 49923..........6RqGcuser_info: nickname: tsechingho email: [email protected] first_name: Tse-Ching last_name: Ho name: Tse-Ching Ho image: http://graph.facebook.com/1290347368/picture?type=square urls: Facebook: http://www.facebook.com/tsechingho Website:extra: user_hash: id: "1290347368" name: Tse-Ching Ho first_name: Tse-Ching last_name: Ho link: http://www.facebook.com/tsechingho username: tsechingho hometown: id: "110922325599480" name: Taichung, Taiwan

Page 32: devise tutorial - 2011 rubyconf taiwan

FACEBOOK

Page 33: devise tutorial - 2011 rubyconf taiwan

NEW FACEBOOK APPhttps://developers.facebook.com/apps

developers.facebook.com

Page 34: devise tutorial - 2011 rubyconf taiwan

CORRECT APP SETTINGSapp id, app secret, site url, site domain are required.

developers.facebook.com

Page 35: devise tutorial - 2011 rubyconf taiwan

FACEBOOK USER PANELhttp://www.facebook.com/settings?tab=applications

https://developers.facebook.com/docs/reference/api/permissions/

facebook.com

Page 36: devise tutorial - 2011 rubyconf taiwan

• ca_file / ca_path

• /users/auth/facebook

• users/omniauth_callbacks#passthru

• https://www.facebook.com/connect/uiserver.php

• /users/auth/facebook/callback?code=xxxxxx

FACEBOOK OAUTH WORK FLOW

facebook.com

Page 37: devise tutorial - 2011 rubyconf taiwan

TWITTER

Page 38: devise tutorial - 2011 rubyconf taiwan

NEW TWITTER APPhttps://dev.twitter.com/apps/newuse http://127.0.0.1 for localhost

dev.twitter.com

Page 39: devise tutorial - 2011 rubyconf taiwan

CORRECT APP SETTINGSconsumer key, consumer secret, callback url are required.

dev.twitter.com

Page 40: devise tutorial - 2011 rubyconf taiwan

TWITTER USER PANELyou can stop it, not remove it.

twitter.com

Page 41: devise tutorial - 2011 rubyconf taiwan

• /users/auth/twitter

• users/omniauth_callbacks#passthru

• https://api.twitter.com/oauth/authenticate

• /users/auth/twitter/callback?code=xxxxxx

• twitter auth data is too big for cookies session store

• no email in user auth data

TWITTER OAUTH WORK FLOW

api.twitter.com

Page 42: devise tutorial - 2011 rubyconf taiwan

GITHUB

Page 43: devise tutorial - 2011 rubyconf taiwan

NEW GITHUB APPhttps://github.com/account/applications/new

github.com

Page 44: devise tutorial - 2011 rubyconf taiwan

CORRECT APP SETTINGSclient id, client secret, callback url are required.

github.com

Page 45: devise tutorial - 2011 rubyconf taiwan

GITHUB APP/USER PANEL ?Don’t delete oauth application,

otherwise you have to create new one.

github.com

Page 46: devise tutorial - 2011 rubyconf taiwan

• /users/auth/github

• users/omniauth_callbacks#passthru

• https://github.com/login/oauth/authorize

• /users/auth/github/callback?code=xxxxxx

GITHUB OAUTH WORK FLOWgithub.com

Page 47: devise tutorial - 2011 rubyconf taiwan

GIT CHECKOUT OA-OPENID

Page 48: devise tutorial - 2011 rubyconf taiwan

GOOGLE

Page 49: devise tutorial - 2011 rubyconf taiwan

SIGN IN GOOGLE ACCOUNT

Page 50: devise tutorial - 2011 rubyconf taiwan

• ca_file / open_id_store

• /users/auth/google

• users/omniauth_callbacks#passthru

• https://www.google.com/accounts/o8/ud

• https://accounts.google.com/o/openid2/auth

• https://www.google.com/accounts/o8/id?id=xxxxxx

• /users/auth/google/callback

GOOGLE OPENID WORK FLOW

Page 51: devise tutorial - 2011 rubyconf taiwan

YAHOO

Page 52: devise tutorial - 2011 rubyconf taiwan

SIGN IN YAHOO ACCOUNT

Page 53: devise tutorial - 2011 rubyconf taiwan

• ca_file / open_id_store

• /users/auth/yahoo

• users/omniauth_callbacks#passthru

• https://open.login.yahooapis.com/openid/op/auth

• https://login.yahoo.com/config/login

• https://me.yahoo.com/a/xxxxxx

• /users/auth/yahoo/callback

YAHOO OPENID WORK FLOW

Page 54: devise tutorial - 2011 rubyconf taiwan

GOOGLE APPS

Page 55: devise tutorial - 2011 rubyconf taiwan

SIGN IN GOOGLE ACCOUNThttp://www.google.com/enterprise/marketplace/

http://developer.googleapps.com/marketplace/getting-started

Page 56: devise tutorial - 2011 rubyconf taiwan

• ca_file / open_id_store

• /users/auth/gmail

• users/omniauth_callbacks#passthru

• https://www.google.com/accounts/o8/ud?source=gmail.com

• https://accounts.google.com/o/openid2/auth

• https://www.google.com/accounts/o8/id?id=xxxxxx

• /users/auth/gmail/callback

GOOGLE APPS OPENID WORK FLOW

Page 57: devise tutorial - 2011 rubyconf taiwan

ISSUES

Page 58: devise tutorial - 2011 rubyconf taiwan

FINDING USER ?

Page 59: devise tutorial - 2011 rubyconf taiwan

USERNAMEVS

UNCHANGEABLE EMAIL

Page 60: devise tutorial - 2011 rubyconf taiwan

ONE EMAIL - ONE USERVS

ONE USER - MULTI EMAILS

Page 61: devise tutorial - 2011 rubyconf taiwan

IF EMAIL OF PROVIDER USER CHANGED,

THEN >.<

Page 62: devise tutorial - 2011 rubyconf taiwan

PUBLIC EMAIL ADDRESSVS

PROVIDER - UID PAIR

Page 64: devise tutorial - 2011 rubyconf taiwan

ONE PROVIDER - ONE USERVS

ONE USER - MULTI PROVIDERS

Page 65: devise tutorial - 2011 rubyconf taiwan

OWN LOCAL USER FIRSTOR

OWN PROVIDER USER FIRST

Page 66: devise tutorial - 2011 rubyconf taiwan

ONE USERMULTI MAILS

MULTI PROVIDERS

Page 67: devise tutorial - 2011 rubyconf taiwan

RESOURCES

Page 70: devise tutorial - 2011 rubyconf taiwan

Q & A