はじめに
FacebookでOmniAuthでユーザー認証しましょう。かっこいいからです。
似たような記事はたくさんありますが、Facebookの仕様変更などで、記事単体では実装が完了しないものばかりだったので改めて書くことにしました。
まずdeviseのみで認証機能を実装
以下のサイトを参考につくります。
【Railsのアプリ開発】初心者でもわかる!deviseでログイン機能を実装する使い方
暇があれば上の内容も自分でしっかり解説して書きたいところですが、「暇があれば」などと言うのは大体やらない兆しです。期待しないでください。
ユーザー一覧ページの作成
認証ページだけ作っても寂しいので、ユーザー一覧ページを作っておくと良いでしょう。
$ rails g controller users
これで作成されるファイルのうち、コントローラーとビューを以下のように変更して、ユーザー一覧ページを作成します。
class UsersController < ApplicationController
before_action :authenticate_user!
def index
@users = User.all
end
end
<% @users.each do |u| %>
<div class="user_field">
<%= link_to u.email, destroy_user_session_path, method: :delete %>
</div>
<% end %>
一覧表示されたユーザーのメールアドレスをクリックするとサインアウトするようにしました。
最後に、このusers#indexアクションへのルーティングを設定しておきます。
Rails.application.routes.draw do
# 省略
resources :users, only: [:index]
root "users#index"
end
サインイン後にはルートパスにリダイレクトされるので、簡単にサインインできたかどうかの確認ができるように、"users#index"をルートパスに設定しました。
Facebookでのサインインに成功すれば、ユーザー一覧のページに遷移し、そこに自分がFacebookに登録したメールアドレスが表示されるはずです。
omniauthを実装
再び以下のサイトを参考に。
【開発メモ】RailsアプリでFacebookログインの認証機能を実装させる方法
暇があれば。
Facebookの変更に対応
2019/2/15時点で、これだけではまだ足りません。
Facebook側の仕様変更で、以下が必須になりました。
- アプリケーションにhttpsでアクセスするように設定する
- プライバシーポリシーを載せたURLを指定する
順にやっていきます。
アプリケーションにhttpsでアクセスできるように設定する
httpsでアクセスできるようにするには、アプリケーションサーバーがSSL証明書というものを持っていないといけません。SSL証明書にはグレードがあり、グレードの高いものほどサイトの安全性を保証できるのですが、それらは発行するのに認証局にたくさんお金を払わなければなりません。
しかしグレードの低いもので良ければ、自分で作成することができます。自分で作成といってもよくわからないので、SSL証明書の作成はmkcertを使って楽にやってしまいましょう。
また、RailsのアプリケーションサーバーとしてPumaを使えば、SSL証明書に関するなんやかんやをいい感じにやってくれます。
PumaはRails5では標準のアプリケーションサーバーなので、これに関しては特にややこしいことはありませんが、何かこだわりや制約があって他のアプリケーションサーバーを使う場合はブラウザバックです。
mkcertでSSL証明書を作成
公式GitHub: FiloSottile/mkcert
READMEを読んで、mkcertをインストールします。
僕のパソコンはmacなので、Homebrewを使います。
$ brew install mkcert
$ mkcert -install
自分のRailsアプリケーションの適当な場所にSSL証明書を置くディレクトリを作り、SSL証明書を作成します。
$ mkdir config/certs && cd config/certs
$ mkcert localhost
これで、config/certs
ディレクトリ内にlocalhost.pem
と localhost-key.pem
という名前のSSL証明書ができます。
以下のように配置されていればOKです。
.gitignoreでSSL証明書を無視
SSL証明書はgitで管理したくないので、.gitignoreに追記します。
(省略)
/config/certs/*
pumaの設定ファイルでSSL証明書を指定する
config/puma.rb
の12行目くらいに、httpでのpumaのサーバーを3000番のポートで起動するという設定の一行があります(port ENV.fetch("PORT") { 3000 }
)。
httpsでアクセスできるようにしたい今、これはもはや必要ないのでコメントアウトし、以下のように3000番の座を乗っ取りましょう。
(省略)
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
#
# port ENV.fetch("PORT") { 3000 }
ssl_bind "0.0.0.0", "3000", {
cert: "config/certs/localhost.pem",
key: "config/certs/localhost-key.pem"
}
アクセスしてみる
あとはいつもどおりサーバーを立ち上げてhttps://localhost:3000
にアクセスするだけです(httpではなくhttpsです!)。
$ rails server
プライバシーポリシーを載せたURLを指定する
プライバシーポリシーとは、収集した情報をこれこれこういう目的で使いますよという旨が書かれた文書のことです。とりあえず開発時にはアクセスできるサイトであればなんでもよいです。アプリケーションを公開する段階になったら、忘れずに自分のアプリケーション内にプライバシーポリシーを載せたページを作り、それを指定しましょう。
facebookの開発者用管理ページに以下のようにURLを設定しておきます。
プライバシーポリシーのURLの設定は以上です!簡単!
確認
https://localhost:3000
にアクセスすると、サインインのページに遷移し、そこに「Sign in with Facebook」というリンクが表示されているはずです。これをクリックするとFacebookの認証画面が現れて…。自分のメールアドレスが表示されたでしょうか?
できたはずです。きっと…。
[+α] deviseで使われるビューファイルを確認する
deviseで作成される諸々のユーザー認証のページは、そのままでは見ることもできません。
しかし以下の設定とコマンドで、ユーザー認証まわりのビューファイルを確認し、カスタマイズすることができるようになります。
config/initializers/devise.rb
の238行目を以下のように書き換えます。
config.scoped_views = true
config/initializers
ディレクトリの中に入っているファイルを変更したので、もしサーバーを立ち上げていたらサーバーを再起動してください。このディレクトリの中のファイルはサーバー立ち上げ時にだけ読み込まれるからです。
続いて、ビューファイルを作成します。
$ rails g devise:views users
こうしてできたビューファイルのうち、app/views/users/shared/_links.html.erb
を見てみると、下の方に以下のような記述があります。これが Sign in with Facebook
などと表示してくれる部分です。
<%- 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 %>
deviseで作成したモデルにomniauthableというオプションがついていれば、この部分が表示され、サインインボタンが表示されるようになっています。今回はデザインまではいじりませんが、かっこいいユーザー認証ページを作成したければここを変えればいいということを覚えておいてください。