Overview
To implement the Facebook login (OAuth) in Rails.Operating environment
- Ruby on Rails 4.2.0
- Ruby 2.1.0p0
- Devise 3.4.1
- OmniAuth 1.2.2
- OmniAuth-facebook 2.0.0
- OmniAuth-twitter 1.1.0
Advance preparation
To get the Facebook API key.
https://developers.facebook.com make a app.
Once created, select the "Add Platform" → "Website" than the set.
To enter the URL to the site URL.
To enter the URL to the site URL.
Gemfile
gem 'omniauth-facebook'
config / initializers / omniauth.rb
Rails. Application. Config. Middleware. Use OmniAuth :: Builder do
provider: facebook, ENV [ 'FACEBOOK_KEY '], ENV [ 'FACEBOOK_SECRET']
end
Since FACEBOOK_KEY and FACEBOOK_SECRET the environment variables, in the case of Toka CentOS to edit something the ~ / .bash_profile.
Configuring Routing
Page failure, when the login fails for some reason, to be displayed.
Link on the login button
/auth/facebook
is. get '/ auth /: provider / callback', to: 'users # create', as:: auth_callback
get '/ auth / failure', to: 'users # auth_failure', as:: auth_failure
controller
Use the information that comes back from Facebook, or create a user, you or to log.
Every time of login, because I want to update the icon and name, and @ user.save.
It does not describe sign_in method, but only by substituting the user of the relevant to current_user.
Every time of login, because I want to update the icon and name, and @ user.save.
It does not describe sign_in method, but only by substituting the user of the relevant to current_user.
from_omniauth
methods and context: :facebook_login
For by model.Because it contains a variety information in env [ 'omniauth.auth'], it passes as an argument.
controllers / users_controller.rb
def create
if env [ 'omniauth.auth']. present?
# Facebook login
@user = User. from_omniauth (env [ 'omniauth.auth'])
. result = @user save (context: : facebook_login)
fb = "Facebook"
else
# Usually sign up
@user = User. new (strong_params)
result = @user. save
fb = ""
end
if result
sign_in @user
flash [: success] = "# {fb} has been logged."
redirect_to @user
else
if fb. present?
redirect_to auth_failure_path
else
render 'new'
end
end
end
model
If it finds the same e-mail address, log in as that user.
Otherwise, you create a new user.
Otherwise, you create a new user.
In the Facebook login, so you do not need a password, you have to disable the password validation.
on: :facebook_login
Keep in addition to, when you save the controller@user.save(context: :facebook_login)
and to have.
models / user.rb
validates: password, presence: false, on:: facebook_login
def self. from_omniauth (auth)
# Provision of email is mandatory
user = User. where ( 'email =?', auth. info. email). first
if user. blank?
user = User. new
end
user. uid = auth. uid
user. name = auth. info. name
user. email = auth. info. email
user. icon = auth. info. image
user. oauth_token = auth. credentials. token
user. oauth_expires_at = Time. at ( auth. credentials. expires_at)
user
end
/ If you hit the auth / facebook, it is displayed dialog of Facebook.
1. implementation of the email address authentication
Editing of Gemfile
Gemfile
gem 'devise'
Installation
$ Bundle install
Generates each file of Devise
$ Rails g devise: install
create config / initializers / devise.rb
create config / locales / devise.en.yml
================================================== =============================
Some setup you must do manually if you have not yet:
. 1. Ensure you have defined default url options in your environments files Here is an example of default_url_options appropriate for a development environment in config / environments / development.rb:
config.action_mailer.default_url_options = {host: 'localhost', port: 3000}
In production,: host should be set to the actual host of your application.
2. Ensure you have defined root_url to * something * in your config / routes.rb.
For example:
root to: "home # index"
3. Ensure you have flash messages in app / views / layouts / application.html.erb.
For example:
<% = Notice%>
<% = Alert%>
4. If you are deploying on Heroku with Rails 3.2 only, you may want to set:
config.assets.initialize_on_precompile = false
On config / application.rb forcing your application to not access the DB
or load models when precompiling your assets.
5. You can copy Devise views (for customization) to your app by running:
rails g devise: views
================================================== =============================
Japanese the Devise
config/locales/devise.en.yml
the devise.ja.yml
to rename to.
To copy and paste the following contents.
Of course Rails app itself it is necessary to Japanese localization.
Of course Rails app itself it is necessary to Japanese localization.
- devise-i18n / ja.yml at master · tigrish / devise-i18n
config / locales / devise.ja.yml
ja:
devise:
confirmations:
confirmed: I registered the account.
send_instructions: will contact you by e-mail how to register within a few minutes.
send_paranoid_instructions: If the e-mail address is registered, you will receive an e-mail how to verify your account within a few minutes have been described.
:
Generate a User model
By using the generator Devise, it can be generated in advance model file module is defined.
$ Rails g devise User
Edit the module to use
In the User model,
In order to enable the Fasebook authentication
devise
can define whether to use any module by the method.In order to enable the Fasebook authentication
devise
the method:omniauthable
also want to add.
app / models / user.rb
# Include default devise modules Others available are .:
#: Confirmable,: lockable,: timeoutable and: omniauthable
devise: database_authenticatable,: registerable,
: recoverable,: rememberable,: trackable ,: validatable,
: omniauthable, omniauth_providers: [: facebook ]
See the README for the available modules.
Execution of migration
rails g devise User
when the db/migrate/xxx_devise_create_users.rb
has also been generated migration file named.This will be applied to the DB.
$ Rake db: migrate
== 20150207093749 DeviseCreateUsers: migrating ================================ - create_table (: users)
-> 0.0800s
- Add_index (: users,: email, {: unique => true})
-> 0.0659s
- Add_index (: users,: reset_password_token, {: unique => true})
-> 0.0528s
== 20150207093749 DeviseCreateUsers: migrated (0.1993s) =======================
Display of the sign-up form
Or more,
It is ready for user registration at this time.
http://〜/users/sign_up
access to when the form is displayed.It is ready for user registration at this time.
2. authentication with OAuth
Editing of Gemfile
Gemfile
gem 'omniauth'
gem 'omniauth-facebook'
gem 'omniauth-twitter'
Installation
$ Bundle install
Creating a 8.Authentication model
But may be added a column to the originally a User model, we want to be able to log in to the same account in the accounts of a number of services, User model to create the Authentication model that has_many.
$ Rails g model authentication user_id: integer provider: string uid: string
invoke active_record
create db / migrate / 20150208043543_create_authentications.rb
create app / models / authentication.rb
invoke test_unit
create test / models / authentication_test.rb
create test / fixtures / authentications.yml
The User model as a "has_many", and "belongs_to" in the User model the Authentication model.
app / models / user.rb
class User
has_many: authentications, dependent:: destroy
end
app / models / authentication.rb
class Authentication
belongs_to: user
end
Execution of migration
$ Rake db: migrate
== 20150207101521 AddColumnsToUsers: migrating ================================
- Add_column (: users,: uid ,: string)
-> 0.1305s
- Add_column (: users,: provider ,: string)
-> 0.1113s
== 20150207101521 AddColumnsToUsers: migrated (0.2424s)=======================
Acquisition of API key
To create a more applications below.
Once created, select the "Add Platform" → "Website" than the set.
To enter the URL to the site URL (for example:
To enter the URL to the site URL (for example:
http://192.168.33.10:3000/
).
To create a more applications below.
Once created, make the following settings from the "Settings".
- Callback URL
- Example:
http://〜/users/auth/twitter
- Example:
- The following is checked:
- Allow this application to be used to Sign in with Twitter
reference
Setting of Devise
Setting each key of the provider that acquired above.
Each API key for security is set to environment variable.
If you divide the development / staging / production environment
Each API key for security is set to environment variable.
If you divide the development / staging / production environment
Rails.env.production?
Distributed by using a.
config / initializers / devise.rb
Devise. Setup do | Config |
# ...
config. omniauth : facebook, ENV [ 'FACEBOOK_ID' ], ENV [ 'FACEBOOK_SECRET']
config. omniauth : twitter, ENV [ 'TWITTER_KEY' ], ENV [ 'TWITTER_SECRET']
end
Implement the find method in the User model
uid
and provider
combination of is unique, thereby obtaining the user.If that does not exist in the record to be created.
app / models / user.rb
class User
# ...
def self. find_for_oauth (auth)
. user = User where. (uid :. auth uid, provider:. auth provider) first
unless user
user = User. create (
uid:. auth uid,
provider:. auth provider,
email:. User dummy_email (auth) ,
password:. Devise friendly_token [0, 20]
)
end
user
end
private
def self. dummy_email (auth)
"# {Auth uid.} - # {. Auth provider} @ example.com"
end
end
If the authentication of the e-mail address has been implemented, it is necessary that the time of authentication with OAuth also to save the e-mail address.
Here,
Here,
uid
and the provider
using a combination of that unique,self.dummy_email
are generated as.reference
- http://stackoverflow.com/questions/18504308/getting-omniauth-facebook-and-omniauth-twitter-work
- http://sourcey.com/rails-4-omniauth-using-devise-with-twitter-facebook-and-linkedin/
- http://easyramble.com/devise-and-omniauth-specs.html
Implement a callback processing to User controller
app/controllers/users
ディレクトリを作成し、omniauth_callbacks_controller.rb
を作ります。
provider
there is a need to define a method with the same name as the.However, because the call-back process of basically each provider are common,
callback_from
are unified in method.
app / controllers / users / omniauth_callbacks_controller.rb
class Users :: OmniauthCallbacksController
def facebook
callback_from: facebook
end
def twitter
callback_from: twitter
end
private
def callback_from (provider)
provider = provider. to_s
@user = User. find_for_oauth (request. env [ 'omniauth.auth'])
if @user. persisted?
flash. [: notice] = I18n t ( 'devise.omniauth_callbacks.success', kind:. provider capitalize)
sign_in_and_redirect @user, event:: authentication
else
session [ "devise. # {provider } _data"] = request. env [ 'omniauth.auth']
redirect_to new_user_registration_url
end
end
end
Routing processing
As follows, to set the routing for OAuth callback.
config / routes.rb
Rails. Application. Routes. Draw do
devise_for : users, controllers: {
omniauth_callbacks: 'users / omniauth_callbacks'
}
# ...
end
Add the authentication link
Link by the following is generated.
Describing it in any position of view.
Describing it in any position of view.
user_omniauth_authorize_path (: facebook)
user_omniauth_authorize_path (: twitter)