Disclaimer: This plugin CANNOT be used alongside other Authlogic extensions like authlogic_oauth and authlogic_openid due to an unfortunate bug caused by all these plugins overriding the ActiveRecord save method to avoid a DoubleRenderError.
config.gem "authlogic" config.gem "oauth2" config.gem "authlogic_oauth2" $ sudo rake gems:install
For older version of Rails, you can install authlogic_oauth2 as a plugin:
$ script/plugin install git://github.com/andyhite/authlogic_oauth2.git
For information about how to set up and configure authlogic, please consult the authlogic README (github.com/binarylogic/authlogic)
class AddOauth2FieldsToUser < ActiveRecord::Migration def self.up add_column :users, :oauth2_token, :string add_index :users, :oauth2_token end def self.down remove_column :users, :oauth2_token end end
IMPORTANT: make sure that you allow null values for crypted_password and password_salt if they aren’t required for OAuth2 users.
The oauth2_client_id, oauth2_client_secret and oauth2_site configuration values must be specified so we can initialize the connection with your OAuth2 provider. The oauth2_scope value is optional, and is used to request extended permissions from your provider.
Here’s an example for Facebook:
class UserSession < Authlogic::Session::Base oauth2_client_id "APPLICATION_ID" oauth2_client_secret "APPLICATION_SECRET" oauth2_site "https://graph.facebook.com" oauth2_scope "offline_access,email,user_birthday" oauth2_cannot_find_record_message "We have no record of you in our database, please sign up first." end
It’s important to note here that if you don’t request offline_access permissions from your OAuth2 provider the access token will expire either at a specific time or upon logout from the provider itself. Some providers allow refresh tokens to be issued, but some (Facebook, for example) does not. Refresh token handling hasn’t been implemented in authlogic_oauth2 yet, so make sure you request offline_access.
We need to redirect the user to their oauth2 provider so they can authenticate and then pick things back up when they’re returned, so any calls to User#save or UserSession#save need to be updated to the following format:
@user.save do |result| if result # Do something else # Do something else end end
and
@user_session.save do |result| if result # Do something else # Do something else end end
In file app/views/user_sessions/new.html.erb:
<% form_for @user_session, :url => user_session_path do |f| %> # All your other form stuff goes here, if you need it. <%= oauth2_login_button :value => "Login using Facebook" %> <% end %>
In file app/views/users/new.html.erb:
<% form_for @user, :url => account_path do |f| %> # All your other form stuff goes here, if you need it. <%= oauth2_register_button :value => "Register using Facebook" %> <% end %>
If you followed these steps correctly, then you should be able to register and login using OAuth2.
You can easily access any API endpoints that are exposed to an OAuth2 user by utilizing the oauth2 gem’s “get” method on current_user#oauth2_access. For instance, you can access information about the currently logged in user’s Facebook profile by doing the following:
current_user.oauth2_access.get('/me')
This will return a JSON string representing the user’s profile information.
You can pre-populate user information by using the after_oauth2_authentication hook in your user model:
require 'json' class User < ActiveRecord::Base ... def after_oauth2_authentication json = oauth2_access.get('/me') if user_data = JSON.parse(json) self.name = user_data['name'] self.facebook_uid = user_data['id'] end end end
You can get more information about the Facebook Graph API on the following website: developers.facebook.com/docs/api