【Ruby on Rails】DeviseなしのUserモデルにOauth認証を追加する方法
Oauth認証とは
Open Authorization 認証の略です。読み方は「オーオース」らしい。
ざっくりいうとTwitterやFacebookのアカウント情報でログインできるようになります。
アイコン画像も取ってこれるので、ユーザーとしては登録の手間がかなり省けて便利です。
まずはAPIを取得する必要がある。
こちらを参考にDeveloperとして登録します。しかし、Describe in your own words what you are buildingの欄のみリンクと違い、4つの質問に一つ一つ答えていく形式に変わっています。(2019年4月10日現在)
大まかに日本語に訳すと、以下の事柄について聞かれています。
すべて合わせて、300文字以上書く必要があります。
1.どのような目的やケースでツイッターのAPIを使うのか
2.ツイートやユーザーなどを分析するつもりかどうか。もしするなら、その方法や技術と詳細を記述。
3.ツイート、リツイート、リンクを含んだ使い方をするかどうか。もしするなら、ユーザーやコンテンツをやりとりする方法を記述。
4.どのようにツイッターの情報が表示されるのか。もしツイッターからコンテンツを表示するなら、アプリのどこにどのように表示されるのかを記述(それぞれのツイートやツイッターのコンテンツが表示されるのか、それともまとめた情報が表示されるのか)
Developerの登録が終わったら、こちらにいき、右上の「Create an app」からAPIを使うアプリを登録します。
「App name」や「Website URL」は特に問題ないですが、Callback URLsに関してはURLが2つ以上登録されていないと正しく動作しません。
ローカル環境の場合は以下の2つのURLを登録します。
http://127.0.0.1:3000/auth/twitter/callback
http://localhost:3000/auth/twitter/callback
また本番環境のときには、localhost:3000や127.0.0.1:3000の部分をドメイン名に書き換えたURLを一つ追加すればOKです。
次にKeys and tokensからConsumer API keysをを取得します。
このAPI KeyとAPI secret keyを後で使用します。
Access token & access token secretについては認証やツイートを取得するだけであれば必要ありません。
gemのインストール
各種gemをインストールしていきます。
twitter認証用のgem
gem 'omniauth'
gem 'omniauth-twitter'
先ほどのConsumer API keysはGitHubに上げたくないので、環境変数に入れます。
今回は.bash_profileなどには入れず、gemで管理したいと思います。
gem 'dotenv-rails'
bundle
します。
設定
まずは環境変数の設定をします。
直下の.env
(なければ作成)に以下を追記します。
TWITTER_CONSUMER_KEY = (先ほど取得したAPI Key)
TWITTER_CONSUMER_SECRET = (先ほど取得したAPI secret key)
.env
を.gitignore
に追加するのを忘れないようにしてください。
route.rb
に以下を追記します
get 'auth/:provider/callback', to: 'sessions#create'
次にconfig/initializers/omniauth.rb
を作成し、以下を設定
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, ENV['TWITTER_CONSUMER_KEY'], ENV['TWITTER_CONSUMER_SECRET'],
end
実装
次にuserモデルにuid, provider、もしなければimageのためのカラムも追加します。
providerで何のサービスかを判断し、uidでどのユーザーかを識別しています。
class AddColumnsToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :uid, :string
add_column :users, :provider, :string
add_column :users, :image_url, :string
end
end
rails db:migrate
後、Userモデルには以下を追記します。
def self.find_or_create_from_auth(auth)
provider = auth[:provider]
uid = auth[:uid]
name = auth[:info][:name]
image = auth[:info][:image]
self.find_or_create_by(provider: provider, uid: uid) do |user|
user.name = name
user.image_url = image
end
end
self.find_or_create_by(provider: provider, uid: uid) do |user|
でcreateが行われていた場合に検証やコールバックが行われるので適時修正する必要があります。
自分の場合は
before_save { self.email.downcase! }
validates :name, presence: true, length: { maximum: 50 }
validates :email, presence: true, length: { maximum: 255 },
format: { with: /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i },
uniqueness: { case_sensitive: false }
has_secure_password
を
before_save :email_downcase, unless: :uid?
validates :name, presence: true, unless: :uid?, length: { maximum: 50 }
validates :email, presence: true, unless: :uid?, length: { maximum: 255 },
format: { with: /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i },
uniqueness: { case_sensitive: false }
has_secure_password validations: false
private
def email_downcase
self.email.downcase!
end
のように修正することで上手くいきました。unless: :uid
を使用するときには処理内容をメソッドとして切り分けないとsyntax errorになります。
次にsessions_controllersを以下のように修正します。
def create
auth = request.env['omniauth.auth']
if auth.present?
user = User.find_or_create_from_auth(request.env['omniauth.auth'])
session[:user_id] = user.id
redirect_to user
else
(従来のログイン処理)
end
end
次に画像の表示の仕方です。
自分の場合はメールアドレスに対応してgravatarのアイコンが表示される実装になっていました。
(プログラミングスクールやRailsチュートリアルではよくある実装だと思います)
そこで、画像を表示するヘルパーを以下に修正
module UsersHelper
def icon_url(user, options = { size: 80 })
if user.email.present?
gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
size = options[:size]
return "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
else
return user.image_url
end
end
end
最後にビューの実装です。
<%= link_to "Twitterアカウントでログイン", "/auth/twitter" %>
まとめ
はまるポイントとしてはCallback URLsが複数必要なこととcreate
で検証やコールバックでつまづくところでしょうか。同じ要領で他のSNSのOauth認証もやっていきたいと思います。
Author And Source
この問題について(【Ruby on Rails】DeviseなしのUserモデルにOauth認証を追加する方法), 我々は、より多くの情報をここで見つけました https://qiita.com/tkr_ld/items/e38a5b92866f41087f57著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .