Summary of the complete facebook and twitter connect flow in a typical rails 3 application, using fbgraph, twitter_oauth.
gem 'fbgraph', '1.9.0'
gem 'twitter_oauth', '0.4.3'
match 'login/:platform' => 'welcome#login', :as => :login
match 'auth/:platform/callback' => 'welcome#auth_callback', :as => :auth_callback
config/social_api.yml:
facebook:
app_key: fbappkey
app_secret: fbappsecret
callback_url: http://yourapp.com/auth/facebook/callback
twitter:
app_key: twtappkey
app_secret: twtappsecret
callback_url: http://yourapp.com/auth/twitter/callback
lib/auth_client.rb
# Interacts with FB/Twitter oauth apis
# using fbgraph and twitter_oauth gems resp.
# Designed to be included to any controller.
module AuthClient
SOCIAL_API_CREDS_MAP = YAML::load_file File.join(Rails.root, 'config/social_api.yml')
#FB methods
def fb_client(reload = false)
opts = {
:client_id => fb_config['app_key'],
:secret_id => fb_config['app_secret'],
:token => session[:fb_access_token]
}
@fb_client = FBGraph::Client.new(opts) if reload
@fb_client ||= FBGraph::Client.new(opts)
end
def fb_authorize
fb_client.authorization.authorize_url(
:redirect_uri => fb_config['callback_url'],
:scope => 'email,publish_stream'
)
end
def fb_get_token(code)
fb_client.authorization.process_callback(code,
:redirect_uri => fb_config['callback_url']
)
end
# TODO:: we may need to check the access token validity as well.
def fb_authorized?
!session[:fb_access_token].blank?
end
def fb_config
SOCIAL_API_CREDS_MAP['facebook']
end
# Twitter methods
def twt_client
opts = {
:consumer_key => twt_config['app_key'],
:consumer_secret => twt_config['app_secret'],
:token => session[:twt_access_token],
:secret => session[:twt_secret_token]
}
@twt_client ||= TwitterOAuth::Client.new(opts)
end
def twt_get_token
twt_client.request_token(
:oauth_callback => twt_config['callback_url']
)
end
def twt_authorize(verifier)
twt_client.authorize(
session[:twt_request_token],
session[:twt_request_token_secret],
:oauth_verifier => verifier
)
end
def twt_authorized?
twt_client.authorized?
end
def twt_config
SOCIAL_API_CREDS_MAP['twitter']
end
end
app/controller/welcome_controller.rb
require 'auth_client'
class WelcomeController < ApplicationController
include AuthClient
def login
self.send(params[:platform] + "_login")
end
def auth_callback
self.send(params[:platform] + "_callback")
end
private
def facebook_login
if fb_authorized?
usr_obj = fb_client.selection.me.info!
check_and_handle_fb_user(usr_obj.data)
else
auth_url = fb_authorize
redirect_to auth_url
end
end
def twitter_login
if twt_authorized?
usr_hsh = twt_client.info
check_and_handle_twt_user(usr_hsh)
else
resp = twt_get_token
session[:twt_request_token] = resp.token
session[:twt_request_token_secret] = resp.secret
redirect_to resp.authorize_url
end
end
def twitter_callback
if params[:denied]
redirect_to login_url(:default), :alert => 'Unauthorized!'
return
end
# Exchange the request token for an access token.
resp = twt_authorize params[:oauth_verifier]
if twt_authorized?
# Storing the access tokens so we don't have to go back to Twitter again
# in this session. We can also consider persisting these details in DB.
session[:twt_access_token] = resp.token
session[:twt_secret_token] = resp.secret
usr_hsh = JSON.parse resp.response.body
check_and_handle_twt_user(usr_hsh)
else
redirect_to login_url(:default), :alert => 'Twitter Auth failed!'
end
end
def facebook_callback
if params[:error] == "access_denied"
redirect_to login_url(:default), :alert => 'Unauthorized!'
return
end
token = fb_get_token(params[:code])
if token
session[:fb_access_token] = token
usr_obj = fb_client(true).selection.me.info!
check_and_handle_fb_user(usr_obj.data)
else
redirect_to login_url(:default), :alert => 'Facebook Auth failed!'
end
end
def check_and_handle_twt_user(usr_hsh)
usr = User.find_by_extuid(usr_hsh['id_str'])
if usr.nil? # new user
@user = User.new(
:username => usr_hsh['screen_name'],
:email => usr_hsh['email'],
:full_name => usr_hsh['name'],
:extuid => usr_hsh['id_str'],
:description => usr_hsh['description'],
:website => usr_hsh['url']
)
@avatar_url = usr_hsh['profile_image_url']
render :signup
else
session[:user_id] = usr.id
redirect_to home_url
end
end
def check_and_handle_fb_user(usr_obj)
usr = User.find_by_extuid(usr_obj.id)
if usr.nil? # new user
@user = User.new(
:username => usr_obj.username,
:email => usr_obj.email,
:full_name => usr_obj.name,
:extuid => usr_obj.id,
:description => usr_obj.bio,
:website => usr_obj.link
)
@avatar_url = fb_client.selection.me.picture
render :signup
else
session[:user_id] = usr.id
redirect_to home_url
end
end
end
User model with username, email, full_name, extuid, description, website, avatar_url columns.
I'll leave it upto you to handle the views, as you would prefer.
will help you get started with the action. Hope it helps!
Gemfile:
gem 'fbgraph', '1.9.0'
gem 'twitter_oauth', '0.4.3'
config/routes.rb:
match 'login/:platform' => 'welcome#login', :as => :login
match 'auth/:platform/callback' => 'welcome#auth_callback', :as => :auth_callback
config/social_api.yml:
facebook:
app_key: fbappkey
app_secret: fbappsecret
callback_url: http://yourapp.com/auth/facebook/callback
twitter:
app_key: twtappkey
app_secret: twtappsecret
callback_url: http://yourapp.com/auth/twitter/callback
# Interacts with FB/Twitter oauth apis
# using fbgraph and twitter_oauth gems resp.
# Designed to be included to any controller.
module AuthClient
SOCIAL_API_CREDS_MAP = YAML::load_file File.join(Rails.root, 'config/social_api.yml')
#FB methods
def fb_client(reload = false)
opts = {
:client_id => fb_config['app_key'],
:secret_id => fb_config['app_secret'],
:token => session[:fb_access_token]
}
@fb_client = FBGraph::Client.new(opts) if reload
@fb_client ||= FBGraph::Client.new(opts)
end
def fb_authorize
fb_client.authorization.authorize_url(
:redirect_uri => fb_config['callback_url'],
:scope => 'email,publish_stream'
)
end
def fb_get_token(code)
fb_client.authorization.process_callback(code,
:redirect_uri => fb_config['callback_url']
)
end
# TODO:: we may need to check the access token validity as well.
def fb_authorized?
!session[:fb_access_token].blank?
end
def fb_config
SOCIAL_API_CREDS_MAP['facebook']
end
# Twitter methods
def twt_client
opts = {
:consumer_key => twt_config['app_key'],
:consumer_secret => twt_config['app_secret'],
:token => session[:twt_access_token],
:secret => session[:twt_secret_token]
}
@twt_client ||= TwitterOAuth::Client.new(opts)
end
def twt_get_token
twt_client.request_token(
:oauth_callback => twt_config['callback_url']
)
end
def twt_authorize(verifier)
twt_client.authorize(
session[:twt_request_token],
session[:twt_request_token_secret],
:oauth_verifier => verifier
)
end
def twt_authorized?
twt_client.authorized?
end
def twt_config
SOCIAL_API_CREDS_MAP['twitter']
end
end
app/controller/welcome_controller.rb
require 'auth_client'
class WelcomeController < ApplicationController
include AuthClient
def login
self.send(params[:platform] + "_login")
end
def auth_callback
self.send(params[:platform] + "_callback")
end
private
def facebook_login
if fb_authorized?
usr_obj = fb_client.selection.me.info!
check_and_handle_fb_user(usr_obj.data)
else
auth_url = fb_authorize
redirect_to auth_url
end
end
def twitter_login
if twt_authorized?
usr_hsh = twt_client.info
check_and_handle_twt_user(usr_hsh)
else
resp = twt_get_token
session[:twt_request_token] = resp.token
session[:twt_request_token_secret] = resp.secret
redirect_to resp.authorize_url
end
end
def twitter_callback
if params[:denied]
redirect_to login_url(:default), :alert => 'Unauthorized!'
return
end
# Exchange the request token for an access token.
resp = twt_authorize params[:oauth_verifier]
if twt_authorized?
# Storing the access tokens so we don't have to go back to Twitter again
# in this session. We can also consider persisting these details in DB.
session[:twt_access_token] = resp.token
session[:twt_secret_token] = resp.secret
usr_hsh = JSON.parse resp.response.body
check_and_handle_twt_user(usr_hsh)
else
redirect_to login_url(:default), :alert => 'Twitter Auth failed!'
end
end
def facebook_callback
if params[:error] == "access_denied"
redirect_to login_url(:default), :alert => 'Unauthorized!'
return
end
token = fb_get_token(params[:code])
if token
session[:fb_access_token] = token
usr_obj = fb_client(true).selection.me.info!
check_and_handle_fb_user(usr_obj.data)
else
redirect_to login_url(:default), :alert => 'Facebook Auth failed!'
end
end
def check_and_handle_twt_user(usr_hsh)
usr = User.find_by_extuid(usr_hsh['id_str'])
if usr.nil? # new user
@user = User.new(
:username => usr_hsh['screen_name'],
:email => usr_hsh['email'],
:full_name => usr_hsh['name'],
:extuid => usr_hsh['id_str'],
:description => usr_hsh['description'],
:website => usr_hsh['url']
)
@avatar_url = usr_hsh['profile_image_url']
render :signup
else
session[:user_id] = usr.id
redirect_to home_url
end
end
def check_and_handle_fb_user(usr_obj)
usr = User.find_by_extuid(usr_obj.id)
if usr.nil? # new user
@user = User.new(
:username => usr_obj.username,
:email => usr_obj.email,
:full_name => usr_obj.name,
:extuid => usr_obj.id,
:description => usr_obj.bio,
:website => usr_obj.link
)
@avatar_url = fb_client.selection.me.picture
render :signup
else
session[:user_id] = usr.id
redirect_to home_url
end
end
end
app/models/user.rb:
User model with username, email, full_name, extuid, description, website, avatar_url columns.
I'll leave it upto you to handle the views, as you would prefer.
link_to 'Facebook Connect', login_path(:facebook)
link_to 'Twitter Connect', login_path(:twitter)
will help you get started with the action. Hope it helps!
for T in `mysql -u root -B -N -e “show tables” test`; do mysql -u root -e “alter table $T type=innodb” test; done
Replace “test” with the target database. This pattern is also great for optimizing or analyzing your MyISAM tables.