ruby on rails
I remember the old days when people had to register for an account separately on each website.
我记得以前人们不得不在每个网站上分别注册一个帐户的日子。
It was a boring and tedious process to repetitively enter the same information over and over again on each website's registration page.
在每个网站的注册页面上一遍又一遍地重复输入相同的信息是一个无聊而乏味的过程。
Times have changed and so has the way people use their preferred websites and services.
时代已经改变,人们使用自己喜欢的网站和服务的方式也发生了变化。
After the advent of the OAuth2 specification, it has become quite a trivial task to allow your users to sign in to your application using a third party service.
OAuth2规范问世之后,允许您的用户使用第三方服务登录到您的应用程序已成为一件微不足道的任务。
Logging in through third party services has become such an important option that if your application does not have it, it seems a bit out-dated.
通过第三方服务登录已经成为一个重要的选择,如果您的应用程序没有它,它似乎有些过时了。
So, in this tutorial, we are going to learn how to allow your users to log in using their social media accounts.
因此,在本教程中,我们将学习如何允许您的用户使用其社交媒体帐户登录。
During the course of this tutorial, you will learn.
在本教程的过程中,您将学习。
This tutorial assumes you have configured Devise without third party authentication and users are able to use your on-site Devise features. It is beyond the scope of this tutorial to demonsrate how to fully customize Devise and setup it's on-site features. The repository for this tutorial includes the code you need to fully set up and customize Devise along with the code discussed as part of this tutorial.
本教程假定您未使用第三方身份验证配置了Devise,并且用户能够使用您的现场Devise功能。 演示如何完全自定义Devise并设置其现场功能超出了本教程的范围。 本教程的资源库包括完全设置和自定义Devise所需的代码,以及本教程中讨论的代码。
Though it is a bit out of scope, however, to round things up nicely, let us have a look at how to create an application through the respective third party websites.
尽管有点超出范围,但是,为了更好地进行汇总,让我们看一下如何通过相应的第三方网站创建应用程序。
Before we begin creating applications, there is a small bit regarding callback url that we need to talk about as we will need it when registering an application.
在开始创建应用程序之前,需要讨论一下有关回调URL的一些内容,因为在注册应用程序时将需要它。
Some of the third party OAuth providers require that you specify a callback url when you create an application.
一些第三方OAuth提供程序要求您在创建应用程序时指定一个回调URL。
The callback url is used to redirect the user back to your application after they have granted permissions to your application and added it to their account.
回调URL用于在用户授予您的应用程序权限并将其添加到他们的帐户后,将用户重定向回您的应用程序。
Devise works by providing a callback url for each provider that you use.
Devise通过为您使用的每个提供程序提供一个回调URL来工作。
The callback url follows the convention
where provider is the gem name which is used to account for a specific third party login strategy.
回调URL遵循惯例
,其中provider是gem名称,用于说明特定的第三方登录策略。
For example, if my application is hosted at http://www.myapp.com
and I have created Devise for the users
entity whom I wish to allow to log in using their Twitter account, the callback url, considering the gem name that provides the strategy is twitter
, would be http://www.myapp.com/users/auth/twitter/callback
.
例如,如果我的应用程序托管在http://www.myapp.com
并且我已为希望允许使用其Twitter帐户登录的users
实体(回调URL)创建了Devise,并考虑了提供的gem名称,该策略是twitter
,即http://www.myapp.com/users/auth/twitter/callback
。
We are going to confirm the callback routes later in this tutorial once we are done setting up the different providers.
设置完不同的提供程序后,我们将在本教程后面确认回调路由。
Log in to your Facebook account and browse to the url https://developers.facebook.com
.
登录到您的Facebook帐户,然后浏览到URL https://developers.facebook.com
。
I am assuming you have not registered for a Facebook developer account and have never created a Facebook application before.
我假设您尚未注册Facebook开发人员帐户,并且之前从未创建过Facebook应用程序。
Click the Register button at the top-right of the page.
单击页面右上方的“ 注册”按钮。
Accept the Facebook developer agreement(in the modal dialog) by turning the switch to YES and clicking the Register button.
通过将开关转到“是”并单击“ 注册”按钮,接受Facebook开发人员协议(在模式对话框中)。
Click the Create App ID button that shows up in the same modal dialog.
单击显示在同一模式对话框中的创建应用程序ID按钮。
Fill in the Display Name, and Contact Email fields and click the Create App ID button.
填写“ 显示名称 ”和“ 联系电子邮件”字段,然后单击“ 创建应用程序ID”按钮。
Once your application is created, you will be taken to the application settings page.
创建应用程序后,将带您进入应用程序设置页面。
Choose Settings > Basic from the left menu.
从左侧菜单中选择设置>基本 。
Enter localhost
in the App Domains field.
在“ 应用程序域”字段中输入localhost
。
Click the Add Platform button at the bottom of the page.
单击页面底部的“ 添加平台”按钮。
Choose Website as the platform.
选择网站作为平台。
Enter http://localhost:3000
in the Site URL field.
在“ 网站URL”字段中输入http://localhost:3000
。
Click the Save Changes button at the bottom of the page.
单击页面底部的“ 保存更改”按钮。
Choose Dashboard from the left menu.
从左侧菜单中选择仪表板 。
Note down the App ID, and App Secret shown on the page as they will be needed later.
记下页面上显示的App ID和App Secret ,因为以后将需要它们。
Log in to your Github account.
登录到您的Github帐户。
Once you have logged in, click your account avatar at the top-right and choose Settings from the drop-down menu.
登录后,单击右上角的帐户头像,然后从下拉菜单中选择设置 。
On the Settings page, choose Developer settings > OAuth applications from the left menu.
在“ 设置”页面上,从左侧菜单中选择开发者设置> OAuth应用程序 。
Click the Register a new application button.
单击注册新应用程序按钮。
Fill in the Application name, Homepage URL, and Application description fields.
填写应用程序名称 , 主页URL和应用程序描述字段。
Enter http://localhost:3000/users/auth/github/callback
in the Authorization callback URL field.
在授权回调URL字段中输入http://localhost:3000/users/auth/github/callback
。
Click the Register application button.
单击注册应用程序按钮。
Once your application is created, you will be taken to the application page.
创建应用程序后,将带您进入应用程序页面。
Note down the Client ID, and Client Secret shown on the page as they will be needed later.
记下页面上显示的Client ID和Client Secret ,因为以后将需要它们。
Log in to your Google account and browse to the url https://console.developers.google.com/apis/library
.
登录到您的Google帐户,然后浏览到URL https://console.developers.google.com/apis/library
。
On the Google developer console, choose Credentials from the left menu.
在Google开发者控制台上,从左侧菜单中选择“ 凭据 ”。
Click the Create credentials button and choose OAuth client ID from the menu that pops up.
单击创建凭据按钮,然后从弹出的菜单中选择OAuth客户端ID 。
For your Application type, choose Web application.
对于您的应用程序类型 ,选择Web应用程序 。
Fill in the Name field.
填写名称字段。
Under the Restrictions section, enter http://localhost:3000
in the Authorized JavaScript origins field.
在“ 限制”部分下的“ 授权JavaScript来源”字段中输入http://localhost:3000
。
Enter http://localhost:3000/users/auth/google_oauth2/callback
in the Authorized redirect URIs field and click the Create button.
在“ 授权重定向URI”字段中输入http://localhost:3000/users/auth/google_oauth2/callback
,然后单击“ 创建”按钮。
Once your application is created, you will be shown the client ID, and client secret in a modal dialog.
创建应用程序后,将在模式对话框中为您显示客户端ID和客户端密码 。
Note down the client ID, and client secret shown in the modal dialog as they will be needed later.
记下在模式对话框中显示的客户端ID和客户端密钥 ,因为稍后将需要它们。
Log in to your Twitter account and browse to the url https://apps.twitter.com
.
登录到您的Twitter帐户,然后浏览到URL https://apps.twitter.com
。
On the Twitter apps page, click the Create New App button.
在Twitter应用程序页面上,单击“ 创建新应用程序”按钮。
Fill in the Name, Description, and Website fields.
填写“ 名称” ,“ 描述 ”和“ 网站”字段。
Enter http://localhost:3000/users/auth/twitter/callback
in the Callback URL field.
在“ 回调URL”字段中输入http://localhost:3000/users/auth/twitter/callback
。
Accept the Developer Agreement and click the Create your Twitter application button.
接受开发者协议 ,然后单击创建您的Twitter应用程序按钮。
On the application page, that is shown next, click the Settings tab.
在接下来显示的应用程序页面上,单击“ 设置”选项卡。
Enter a mock url in the Privacy Policy URL, and Terms of Service URL field and click the Update Settings button.
在“ 隐私政策URL ”和“服务条款URL”字段中输入模拟URL ,然后单击“ 更新设置”按钮。
Click the Permissions tab and change the Access type to Read only.
单击“ 权限”选项卡,然后将“ 访问”类型更改为“ 只读” 。
Check the Request email addresses from users field under the Additional Permissions section and click the Update Settings button.
检查“ 其他权限”部分下的“ 从用户请求电子邮件地址”字段,然后单击“ 更新设置”按钮。
Click the Keys and Access Tokens tab.
单击“ 密钥和访问令牌”选项卡。
Note down the Consumer Key (API Key), and Consumer Secret (API Secret) shown on the page as they will be needed later.
记下他们以后需要在网页上显示的消费密钥(API密钥),和消费者的秘密(API密钥)。
We are going to need a number of gems to make authentication through third party providers work.
我们将需要大量的宝石来使第三方提供商进行身份验证。
Apart from that, we are also going to add two additional gems.
除此之外,我们还将添加两个额外的gem。
The first one will help us store user sessions in the database while the second one will only be used in the development
environment to set environment variables.
第一个将帮助我们将用户会话存储在数据库中,而第二个将仅在development
环境中用于设置环境变量。
The reason we will allow our application to save user sessions in the database is because there is a limit to how much data you can store in a session which is four kilo-bytes. Using database as the session store will overcome this limitation.
之所以允许我们的应用程序将用户会话保存在数据库中,是因为会话中可以存储的数据量为4 KB,这是有限制的。 将数据库用作会话存储将克服此限制。
As for using a gem to set environment variables in the development
environment, it is because we will be using a lot of third party application information that needs to be kept secret.
至于在development
环境中使用gem设置环境变量,这是因为我们将使用许多需要保密的第三方应用程序信息。
Therefore, it is recommended to expose this information to our application as environment variables instead of adding it directly to a configuration file.
因此,建议将此信息作为环境变量公开给我们的应用程序,而不是将其直接添加到配置文件中。
Open the file Gemfile
and add the following gems.
打开文件Gemfile
并添加以下宝石。
# Use Devise for authentication
gem 'devise', '~> 4.2'
# Use Omniauth Facebook plugin
gem 'omniauth-facebook', '~> 4.0'
# Use Omniauth Github plugin
gem 'omniauth-github', '~> 1.1', '>= 1.1.2'
# Use Omniauth Google plugin
gem 'omniauth-google-oauth2', '~> 0.4.1'
# Use Omniauth Twitter plugin
gem 'omniauth-twitter', '~> 1.2', '>= 1.2.1'
# Use ActiveRecord Sessions
gem 'activerecord-session_store', '~> 1.0'
We have started off by adding the Devise gem.
我们首先添加了Devise gem。
Devise gem supports integration with Omniauth which is a gem that standardizes third party authentication for Rails applications.
Devise gem支持与Omniauth集成, Omniauth是使Rails应用程序的第三方身份验证标准化的gem。
Therefore, following the Devise gem, we have simply added the Omniauth strategies we need, namely, facebook
, github
, google-oauth2
, and twitter
.
因此,紧随Devise gem之后,我们仅添加了所需的Omniauth策略,即facebook
, github
, google-oauth2
和twitter
。
Database sessions are facilitated by the activerecord-session_store
gem which has been added towards the bottom.
底部已添加了activerecord-session_store
gem,从而促进了数据库会话。
The last gem we need to add is the dotenv
gem.
我们需要添加的最后一个宝石是dotenv
宝石。
However, since this gem will only be used in the development
environment, we need to add it to the development
group in the Gemfile
.
但是,由于此gem仅在development
环境中使用,因此我们需要将其添加到Gemfile
的development
组中。
Open the Gemfile
, locate the group :development do
declaration, and append the following gem.
打开Gemfile
,找到group :development do
声明,然后添加以下gem。
group:development do
.
.
.
# Use Dotenv for environment variables
gem 'dotenv', '~> 2.2.1'
end
All our gems have been added.
我们所有的宝石都已添加。
Execute the following command at the root of your project to install the added gems.
在项目的根目录执行以下命令以安装添加的gem。
$ bundleinstall --with development
We are done as far as the gems for our project are concerned.
就我们项目的宝石而言,我们已经完成了。
The dotenv
gem we added earlier allows us to create a .env
file at the root of our project and set environment variables easily.
前面添加的dotenv
gem使我们可以在项目的根目录下创建.env
文件,并轻松设置环境变量。
However, if you are using source control like Git, make sure the .env
file is ignored and not committed to your repository as it will contain confidential information.
但是,如果您使用的是Git之类的源代码管理,请确保.env
文件被忽略并且不会提交到您的存储库,因为该文件将包含机密信息。
You can however, add a .env.example
file with placeholder data for the environment variables and commit it to the repository to show other developers on the project how information needs to be added to the .env
file.
但是,您可以添加带有环境变量占位符数据的.env.example
文件,并将其提交到存储库中,以向项目中的其他开发人员展示如何将信息添加到.env
文件中。
Also recall, when creating the third party applications, I instructed you to note down the respective client id and secret which we will be using here.
还记得,在创建第三方应用程序时,我指示您记下我们将在此处使用的相应客户端ID和密码。
Create a .env
file at the root of your project and add the following code.
在项目的根目录下创建一个.env
文件,并添加以下代码。
FACEBOOK_APP_ID=<facebook-app-id>
FACEBOOK_APP_SECRET=<facebook-app-secret>
GITHUB_APP_ID=<github-app-id>
GITHUB_APP_SECRET=<github-app-secret>
GOOGLE_APP_ID=<google-app-id>
GOOGLE_APP_SECRET=<google-app-secret>
TWITTER_APP_ID=<twitter-app-id>
TWITTER_APP_SECRET=<twitter-app-secret>
The
, and
needs to be replaced with your application id and secret.
和
需要用您的应用程序ID和密码替换。
Similarly, replace the remaining placholders with the information provided to you by the respective third parties.
同样,将剩余的placholders替换为相应的第三方提供给您的信息。
For our application configuration, we only need to touch a couple of areas, Devise and the session configuration.
对于我们的应用程序配置,我们只需要涉及两个领域,即Devise和会话配置。
Once we have added our provider application information as environment variables, we need to configure Devise to use it as part of the corresponding provider strategy.
将我们的提供程序应用程序信息添加为环境变量后,我们需要配置Devise以将其用作相应的提供程序策略的一部分。
Open the file config/initializers/devise.rb
and add the following code.
打开文件config/initializers/devise.rb
并添加以下代码。
# ==> OmniAuth
# Add a new OmniAuth provider. Check the wiki for more information on setting
# up on your models and hooks.
config.omniauth :facebook, ENV['FACEBOOK_APP_ID'], ENV['FACEBOOK_APP_SECRET'], scope: 'public_profile,email'
config.omniauth :github, ENV['GITHUB_APP_ID'], ENV['GITHUB_APP_SECRET'], scope: 'user,public_repo'
config.omniauth :google_oauth2, ENV['GOOGLE_APP_ID'], ENV['GOOGLE_APP_SECRET'], scope: 'userinfo.email,userinfo.profile'
config.omniauth :twitter, ENV['TWITTER_APP_ID'], ENV['TWITTER_APP_SECRET']
You can use the comments in the above code snippet to locate the section of the configuration file where you need to add the Omniauth strategy settings.
您可以使用上面的代码片段中的注释来找到配置文件中需要添加Omniauth策略设置的部分。
The config.omniauth
method lets you add and configure an Omniauth strategy.
config.omniauth
方法使您可以添加和配置Omniauth策略。
In our case, we have simply passed the name of the strategy, and the application id and secret using environment variables.
在我们的案例中,我们仅使用环境变量传递了策略的名称以及应用程序ID和密码。
There is also an additional scope
parameter which has been added to some of the providers. It helps us specify the amount of control we wish to have over the authenticated user's data.
还有一个附加的scope
参数已添加到某些提供程序中。 它有助于我们指定希望对经过身份验证的用户数据进行控制的数量。
The reason the scope
parameter is optional is some of the providers allow you to specify the scope when you create an application so there is no need to be explicit in such a case.
scope
参数是可选参数的原因是,某些提供程序允许您在创建应用程序时指定范围,因此在这种情况下无需明确说明。
Also notice, the strategy names(facebook
, github
, google_oauth2
, and twitter
) are the same as the gem name for the respective strategy.
还要注意,策略名称( facebook
, github
, google_oauth2
和twitter
)与相应策略的gem名称相同。
Open the file config/initializers/session_store.rb
and replace the Rails.application.config.session_store
directive with the following code, completely replacing the single line of code contained in the file.
打开文件config/initializers/session_store.rb
并用以下代码替换Rails.application.config.session_store
指令,完全替换文件中包含的单行代码。
Rails.application.config.session_store :active_record_store, key: '_devise-omniauth_session'
And we are done!
我们完成了!
In order to allow our users to login using third party providers, we need to update the users
table, more generally, the entity table you have generated that Devise uses to authenticate users.
为了允许我们的用户使用第三方提供程序登录,我们需要更新users
表,更一般地说,是Devise用来验证用户身份的已生成实体表。
I am going to assume the Devise entity is user but you can very well replace this entity name for your case.
我将假定Devise实体是用户,但您可以根据情况很好地替换该实体名称。
We are also going to create a table to store user sessions.
我们还将创建一个表来存储用户会话。
Execute the following command at the root of your project to generate a update users table migration.
在项目的根目录执行以下命令,以生成更新用户表迁移。
$ rails generate migration update_users
Open the file db/migrate/update_users.rb
and add the following code.
打开文件db/migrate/update_users.rb
并添加以下代码。
class UpdateUsers < ActiveRecord::Migration[5.0]
def change
add_column(:users, :provider, :string, limit: 50, null: false, default: '')
add_column(:users, :uid, :string, limit: 500, null: false, default: '')
end
end
The provider
and uid
fields help to identify a user uniquely as this pair will always have unique values.
provider
和uid
字段有助于唯一标识用户,因为该对将始终具有唯一值。
For our case, the provider can be Facebook
, Github
, Google
, or Twitter
and the uid
will be the user id assigned to a user by any of these third parties.
对于我们的情况,提供者可以是Facebook
, Github
, Google
或Twitter
,而uid
将是由任何第三方分配给用户的用户ID。
Execute the following command at the root of your project to generate a create sessions table migration.
在项目的根目录执行以下命令,以生成创建会话表迁移。
$ rails generate migration create_sessions
Open the file db/migrate/create_sessions.rb
and add the following code.
打开文件db/migrate/create_sessions.rb
并添加以下代码。
class CreateSessions < ActiveRecord::Migration
def change
create_table :sessions do |t|
t.string :session_id, null: false
t.text :data
t.timestamps
end
add_index :sessions, :session_id, unique: true
add_index :sessions, :updated_at
end
end
Our sessions table stores the session id and data with timestamps.
我们的会话表存储会话ID和带有时间戳的数据。
We have also added an index to the session_id
and updated_at
fields respectively as it will help with searching user sessions when they return to our application.
我们还分别在session_id
和updated_at
字段中添加了索引,这将有助于在用户会话返回到我们的应用程序时对其进行搜索。
Execute the following command at the root of your project to migrate the database.
在项目的根目录执行以下命令以迁移数据库。
$ rails db:migrate
You may go ahead and browse the database to make sure the respective tables were created and updated.
您可以继续浏览数据库,以确保创建并更新了相应的表。
We are going to add a method to our user
model that will create the user record in the database using the data provided by the third party provider.
我们将向user
模型添加一种方法,该方法将使用第三方提供商提供的数据在数据库中创建用户记录。
We also need to register the Omniauth strategies in our user
model so that they are picked up by Devise.
我们还需要在user
模型中注册Omniauth策略,以便Devise可以选择它们。
Again, your Devise entity may be different and so will be the model's file name.
同样,您的Devise实体可能有所不同,因此模型的文件名也将有所不同。
Open the file app/models/user.rb
and add the following code.
打开文件app/models/user.rb
并添加以下代码。
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable, :lockable, :timeoutable,
:omniauthable, omniauth_providers: [:facebook, :github, :google_oauth2, :twitter]
def self.create_from_provider_data(provider_data)
where(provider: provider_data.provider, uid: provider_data.uid).first_or_create do | user |
user.email = provider_data.info.email
user.password = Devise.friendly_token[0, 20]
user.skip_confirmation!
end
end
end
The omniauth_providers
array passed to the devise
method helps us register the Omniauth strategies.
该omniauth_providers
阵列传递给devise
方法可以帮助我们注册Omniauth策略。
The array contains symbolized names of the strategies. These names come from and should be same as the gem name for the respective Omniauth strategy.
该数组包含策略的符号名称。 这些名称来自各个Omniauth策略的gem名称,并且应该与它们的gem名称相同。
The create_from_provider_data
method is passed the data provided by the third party and is used to create the user in the database.
create_from_provider_data
方法将传递第三方提供的数据,并用于在数据库中创建用户。
The user is first searched using the provider
string and user id(uid
) by the first_or_create
method.
首先通过first_or_create
方法使用provider
字符串和用户id( uid
)搜索用户。
The first_or_create
method would either fetch the user if it found in the database or create it if it is not present.
如果first_or_create
方法在数据库中找到,则将提取用户;如果不存在,则将创建该用户。
Inside the first_or_create
block, we have simply set the user attributes from the provider data, which for our case is only the user's email.
在first_or_create
块内,我们只需从提供者数据中设置用户属性,在我们的情况下,这只是用户的电子邮件。
There are two parts worth mentioning inside the block.
块内有两个部分值得一提。
The first one is the user.password = Devise.friendly_token[0, 20]
which sets an arbitrary password for the user since it is not exposed by the provider and is required to create a user.
第一个是user.password = Devise.friendly_token[0, 20]
,它为用户设置了任意密码,因为提供者未公开该密码,而创建用户则需要该密码。
The second one is the user.skip_confirmation!
declaration which skips the user email verification process since it has already been verified by the respective provider.
第二个是user.skip_confirmation!
声明,由于相应的提供者已经对其进行了验证,因此跳过了用户电子邮件验证过程。
If you have added other fields to your Devise entity table such as
first_name
,last_name
, anddate of birth
, you can set these fields to the corresponding field values in the third party provider data.如果您已将其他字段(例如
first_name
,last_name
和date of birth
添加到Devise实体表中,则可以将这些字段设置为第三方提供程序数据中的相应字段值。
What we need to work on next is to add the controller that will be handling the third party redirects back to our application.
接下来,我们需要添加控制器,该控制器将处理第三方重定向回我们的应用程序。
Execute the following command to generate an Omniauth callbacks controller.
执行以下命令以生成Omniauth回调控制器。
$ rails generate controller users/omniauth
I have appended users/
before the controller name to generate it under a directory same as the Devise entity.
我在控制器名称之前附加了users/
,以在与Devise实体相同的目录下生成它。
You can change it based on your Devise entity or if you are using multiple Devise entities, you can altogether skip adding the controller under a separate directory by simply executing rails generate controller omniauth
.
您可以根据自己的Devise实体进行更改,或者如果您正在使用多个Devise实体,则可以通过简单地执行rails generate controller omniauth
来完全跳过将控制器添加到单独的目录下的rails generate controller omniauth
。
It is a Devise convention to create a controller method named as the strategy that it will be handling the callback for so we will need to add four methods named facebook
, github
, google_oauth2
, and twitter
respectively to our Omniauth controller.
这是一种Devise约定,创建一个称为策略的控制器方法,该方法将用于处理回调,因此我们需要向我们的Omniauth控制器分别添加四个名为facebook
, github
, google_oauth2
和twitter
的方法。
The controller actions that follow should be added to the app/controllers/users/omniauth_controller.rb
file that we have just created.
随后的控制器操作应添加到我们刚刚创建的app/controllers/users/omniauth_controller.rb
文件中。
# facebook callback
def facebook
@user = User.create_from_provider_data(request.env['omniauth.auth'])
if @user.persisted?
sign_in_and_redirect @user
set_flash_message(:notice, :success, kind: 'Facebook') if is_navigational_format?
else
flash[:error] = 'There was a problem signing you in through Facebook. Please register or try signing in later.'
redirect_to new_user_registration_url
end
end
The user data provided by the third party is available to our application in the request environment variable request.env['omniauth.auth']
so we have passed it to the create_from_provider_data
method we created earlier.
在请求环境变量request.env['omniauth.auth']
,第三方提供的用户数据可用于我们的应用程序,因此我们已将其传递给我们先前创建的create_from_provider_data
方法。
If the user is saved to the database, we set a flash message using the set_flash_message
helper method provided by Devise, sign the user in and redirect them to their homepage.
如果将用户保存到数据库,我们将使用由Devise提供的set_flash_message
帮助器方法设置一条Flash消息,登录该用户并将其重定向到其主页。
In case the user is not saved to the database, a flash error message is set and the user is redirected to the registration page.
如果未将用户保存到数据库,则会设置一条闪存错误消息,并将用户重定向到注册页面。
The code for the remaining provider callbacks is very similar, other than the flash message text.
除Flash消息文本外,其余提供程序回调的代码非常相似。
# github callback
def github
@user = User.create_from_github_data(request.env['omniauth.auth'])
if @user.persisted?
sign_in_and_redirect @user
set_flash_message(:notice, :success, kind: 'Github') if is_navigational_format?
else
flash[:error] = 'There was a problem signing you in through Github. Please register or try signing in later.'
redirect_to new_user_registration_url
end
end
# google callback
def google_oauth2
@user = User.create_from_google_data(request.env['omniauth.auth'])
if @user.persisted?
sign_in_and_redirect @user
set_flash_message(:notice, :success, kind: 'Google') if is_navigational_format?
else
flash[:error] = 'There was a problem signing you in through Google. Please register or try signing in later.'
redirect_to new_user_registration_url
end
end
# twitter callback
def twitter
@user = User.create_from_twitter_data(request.env['omniauth.auth'])
if @user.persisted?
sign_in_and_redirect @user
set_flash_message(:notice, :success, kind: 'Twitter') if is_navigational_format?
else
flash[:error] = 'There was a problem signing you in through Twitter. Please register or try signing in later.'
redirect_to new_user_registration_url
end
end
Apart from the respective provider callbacks, we also need to add a failure callback which Devise will execute for all cases where authentication fails for some reason.
除了各自的提供程序回调之外,我们还需要添加一个失败回调,对于因某种原因而导致身份验证失败的所有情况,Devise将执行该失败回调。
It could be that the redirection failed or the user did not grant permissions to your application.
可能是重定向失败或用户未向您的应用程序授予权限。
Add the following failure callback, below the provider callbacks we added earlier.
在我们之前添加的提供者回调下面添加以下失败回调。
def failure
flash[:error] = 'There was a problem signing you in. Please register or try signing in later.'
redirect_to new_user_registration_url
end
You might think that we need to add the appropriate links to redirect users to third party applications to allow them to sign in to our application but this is taken care of by Devise.
您可能会认为我们需要添加适当的链接以将用户重定向到第三方应用程序,以允许他们登录到我们的应用程序,但这由Devise解决。
Open the file app/views/devise/shared/_links.html.erb
and locate the following code snippet.
打开文件app/views/devise/shared/_links.html.erb
并找到以下代码片段。
<%- if devise_mapping.omniauthable? %>
<%- resource_class.omniauth_providers.each do |provider| %>
<%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider) %><br />
<% end -%>
<% end -%>
The above code snippet checks your Omniauth setup and auto-generates the required links.
上面的代码片段检查您的Omniauth设置并自动生成所需的链接。
Since this shared view is rendered on the sessions/new
view, your users have the option to sign in using your configured providers.
由于此共享视图是在sessions/new
视图上呈现的,因此您的用户可以选择使用配置的提供程序登录。
Isn't Devise a thing of beauty?
设计不是美丽的事物吗?
The last piece of the puzzle is to set up the application routes.
最后一个难题是设置应用程序路由。
Throughout this post, I have assumed that you have an on-site Devise implementation configured and fully functional.
在整个本文中,我假设您已经配置了现场Devise实施并且功能完整。
So, there is a possibility you may already have the following route added to your routes file.
因此,有可能您已经将以下路由添加到了路由文件中。
However, what you need to focus on is the additional controllers
parameter which is used to specify the callbacks controller and will not be present in the route declaration that you have already added.
但是,您需要关注的是附加的controllers
参数,该参数用于指定回调控制器,并且不会出现在已经添加的路由声明中。
Rails.application.routes.draw do
.
.
.
.
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth' }
end
Once you have configured the routes, you can execute the following command to make sure the callback urls were set up correctly.
一旦配置了路由,就可以执行以下命令,以确保正确设置了回调URL。
$ rails routes
Voila! we are all set up to test our application.
瞧! 我们都准备测试我们的应用程序。
We have successfully added third party login through Facebook, Github, Google, and Twitter to our application.
我们已成功通过Facebook,Github,Google和Twitter添加了第三方登录到我们的应用程序。
It is time to take it out for a test drive.
现在是时候将其取出来进行试驾了。
Recall that we are using the dotenv
gem in our development
environment so the command to execute our rails application changes slightly based on that since we also want to set the environment variables to be available to our application.
回想一下,我们在development
环境中使用了dotenv
gem,因此执行Rails应用程序的命令会基于此稍有变化,因为我们还希望将环境变量设置为可用于我们的应用程序。
Execute the following command to start your rails application.
执行以下命令以启动Rails应用程序。
$ dotenv rails server
Browse to Devise's user login page and you should see the text "Sign in with..." for each of the providers we set up.
浏览到Devise的用户登录页面,您应该为我们设置的每个提供商看到文本“使用...登录”。
Here is a screenshot of how it looks with Devise's primitive set up.
这是Devise原始设置的屏幕截图。
Go ahead and try signing in.
继续尝试登录。
You will be taken to the third party provider's webpage where you will be prompted to grant your application access to the user's data.
您将被带到第三方提供商的网页,系统将提示您授予应用程序对用户数据的访问权限。
Once you have done that, you will be taken back to your application, to the user's homepage, with a flash message notifying you of successful sign in.
完成此操作后,您将返回到您的应用程序,回到用户的主页,并显示一条闪烁消息,通知您成功登录。
Here is a screenshot of when the Sign in with Facebook link is clicked through.
这是单击“ 使用Facebook登录”链接时的屏幕截图。
Adding a third party login option to your application is a nice touch and further enhances your application.
在您的应用程序中添加第三方登录选项很不错,可以进一步增强您的应用程序。
Though we have targeted four of the most famous of the lot, you are free to get your hands dirty and try the others available.
尽管我们针对的是其中最著名的四个,但您可以随意弄脏并尝试其他可用的工具。
The Omniauth gem's wiki has a comprehensive list of the strategies available and you should probably get to playing around with them.
Omniauth gem的 Wiki提供了可用策略的完整列表,您可能应该开始使用它们。
I hope you found this tutorial interesting and knowledgeable. Until my next piece, happy coding!
我希望您发现本教程有趣且知识丰富。 直到我的下一篇文章,祝您编程愉快!
翻译自: https://scotch.io/tutorials/integrating-social-login-in-a-ruby-on-rails-application
ruby on rails