devise tutorial - 2011 rubyconf taiwan

Post on 06-May-2015

2.598 Views

Category:

Technology

5 Downloads

Preview:

Click to see full reader

DESCRIPTION

[Tutorial] Build your authentication system with Devise

TRANSCRIPT

BUILD YOUR AUTHENTICATION SYSTEM

WITH DEVISETse-Ching Ho (何澤清)

2011-08-26

HTTPS://GITHUB.COM/TSECHINGHO/DEVISE_TUTORIAL

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

•OminiAuth Client Applicationproviders: Facebook, Twitter, Github

•OpenID Client Applicationproviders: Google, Yahoo, Google Apps

• LDAP Client Applicationproviders: Localhost OpenLDAP

• CAS Client Applicationproviders: Localhost CAS

AGENDA

WHAT IS AUTHENTICATION ?

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

CAS server

devise

omniauth

OpenID providers

Oauth providers

LDAP providers

3rd partyproviders

username /password

customer

DEVISE - OMNIAUTH WAY

WHAT DO WE NEED ?

USER STORY PLEASE

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

WHY DEVISE ?

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

•Database authenticatable

• Token authenticatable

•Omniauthable

• Confirmable

• Recoverable

• Registerable

• Rememberable

• Trackable

• Timeoutable

• Validatable

• Lockable

• Encryptalbe

BUILDED IN MODULES

EXTENSION MODULES

•ORM

• Encryption

• Authentication

• UI enhancement

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

FILTERS & HELPERS

• authenticate_user!

• user_signed_in?

• current_user

• user_session

• user_root_path

DEMO

SHOW, DON’T TELL

GIT LOGS ARE FRIENDS

• 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

GIT CHECKOUT HEROKU

• git checkout heroku

• heroku keys:add

• heroku create

• git push heroku master

• heroku rake db:setup

• heroku open

DEPLOY TO HEROKU

GIT CHECKOUT USER

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

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

GIT CHECKOUT MANAGER

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"}

GIT CHECKOUT PROVIDER

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

GIT CHECKOUT OA-OAUTH

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

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/ }

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

---provider: facebookuid: "1290347368"credentials: token: 49923..........6RqGcuser_info: nickname: tsechingho email: tsechingho@gmail.com 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

FACEBOOK

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

developers.facebook.com

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

developers.facebook.com

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

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

facebook.com

• 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

TWITTER

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

dev.twitter.com

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

dev.twitter.com

TWITTER USER PANELyou can stop it, not remove it.

twitter.com

• /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

GITHUB

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

github.com

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

github.com

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

otherwise you have to create new one.

github.com

• /users/auth/github

• users/omniauth_callbacks#passthru

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

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

GITHUB OAUTH WORK FLOWgithub.com

GIT CHECKOUT OA-OPENID

GOOGLE

SIGN IN GOOGLE ACCOUNT

• 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

YAHOO

SIGN IN YAHOO ACCOUNT

• 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

GOOGLE APPS

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

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

• 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

ISSUES

FINDING USER ?

USERNAMEVS

UNCHANGEABLE EMAIL

ONE EMAIL - ONE USERVS

ONE USER - MULTI EMAILS

IF EMAIL OF PROVIDER USER CHANGED,

THEN >.<

PUBLIC EMAIL ADDRESSVS

PROVIDER - UID PAIR

ONE PROVIDER - ONE USERVS

ONE USER - MULTI PROVIDERS

OWN LOCAL USER FIRSTOR

OWN PROVIDER USER FIRST

ONE USERMULTI MAILS

MULTI PROVIDERS

RESOURCES

Q & A

top related