#GWアドベントカレンダー 「1つサービスを作る」の1日目記事 ツイッターログイン作成
以下の GWアドベントカレンダー 「1つサービスを作る」の1日目記事です。
まずはツイッターログインまで作ります。
Rubyを使う
Rubyのバージョンを選んでインストールする。
※2.7以上は色々有るので、2.6系の最新版2.6.6 にする。
- 一応rbenvをアップデートする。
- インストールできるバージョンの確認をする
- 2.6.6をインストールする。
- 2.6.6 に設定する。
- バージョンを確認する。
brew upgrade rbenv rbenv install -list rbenv install 2.6.6 rbenv global 2.6.6 $ ruby -v
ruby 2.6.6p146 (2020-03-31 revision 67876)
railsを選ぶ
gem をアップデートする。
gem update --system gem -v
今のところ最新版は 3.1.2
のようです。
次にRailsのバージョンを選んでインストールする。
インストール可能なrailsを確認する。
gem list ^rails$ -r -a
今のところ最新版は 6.0.2.2
のようです。
rails (6.0.2.2, 6.0.2.1, 6.0.2, 6.0.1, 6.0.0, 5.2.4.2,
gem install rails -v 6.0.2.2 rails -v
最新版 Rails 6.0.2.2
が入りました。
rails起動まで
新規にプロジェクトを作り、とりあえず起動するまでやる。
rails new profile_card cd profile_card rails db:migrate rails server
起動した。
=> Booting Puma => Rails 6.0.2.2 application starting in development => Run `rails server --help` for more startup options Puma starting in single mode... * Version 4.3.3 (ruby 2.6.6-p146), codename: Mysterious Traveller * Min threads: 5, max threads: 5 * Environment: development * Listening on tcp://[::1]:3000 * Listening on tcp://127.0.0.1:3000 Use Ctrl-C to stop
ツイッターログインする
※Twitter Developerは登録済みです。
Gemを入れる
Gemfile に以下の1つを追加する。
gem 'devise'
Gemをインストールする。
bundle install
devise関連の設定をする
rails generate devise:install
だらだらとメッセージが出てきます。
Running via Spring preloader in process 3607 create config/initializers/devise.rb create config/locales/devise.en.yml ===============================================================================
とりあえず無視します。(雑やな・・・)
先にユーザーモデルを作ってしまいます。
rails generate devise user rake db:migrate rails server
以下にアクセスする。
http://localhost:3000/users/sign_up
ログイン画面が出ました。
omniauth-twitterなどの追加
Gemfile に以下を追加する。
gem 'omniauth-twitter'
追加したらGemをインストールする。
bundle install
userモデルの変更
次にuserモデルに、OmniAuthで必要なuidとproviderを追加します。
rails generate migration AddColumnsToUsers uid:string provider:string rake db:migrate
devise.rbの変更
config.omniauth のところにツイッターログインの情報を書き込みます。
'API KEY'と 'API SECRET'はTwitter Developerの情報を書き入れます。
config/initializers/devise.rb
config.omniauth :twitter, 'API KEY', 'API SECRET', callback_url: "http://127.0.0.1:3000/users/auth/twitter/callback"
userモデルの変更
Userモデルの対応はstackoverflowを参考に対応する。
stackoverflow.com
app/models/user.rb
devce に , :omniauthable
を追加して、first_or_create でユーザーが存在するときにユーザーを返して、そうでないときはユーザー作成するようにします。
def self.from_omniauth(auth) where(provider: auth.provider, uid: auth.uid).first_or_create do |user| user.provider = auth.provider user.uid = auth.uid user.email = User.dummy_email(auth) user.password = Devise.friendly_token[0, 20] end end private def self.dummy_email(auth) "#{auth.uid}-#{auth.provider}@example.com" end
routesの設定
devise_for にコールバック先を教える記述をします。
config/routes.rb を編集します。
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
コールバックの作成
mkdir -p app/controllers/users/
でディレクトリを作成してから、 app/controllers/users/omniauth_callbacks_controller.rb を編集します。
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController def twitter @user = User.from_omniauth(request.env["omniauth.auth"]) if @user.persisted? sign_in_and_redirect @user, event: :authentication #this will throw if @user is not activated set_flash_message(:notice, :success, kind: "Twitter") if is_navigational_format? else session["devise.twitter_data"] = request.env["omniauth.auth"].except("extra") redirect_to new_user_registration_url end end def failure redirect_to root_path end end
参考 qiita.com
データベースに入るか確認
サーバーを起動します。
rails server
以下にアクセスする。
http://localhost:3000/users/sign_up
Sign in with Twitterのリンクをクリックするとツイッター認証後、home画面無いというエラーで終わりますが、認証はできています。
データベースに情報が入っているか確認します。
sqlite3 db/development.sqlite3 select * from users;
データーが入りました。
omniauthの脆弱性対応
Gemfile に以下を追加する。
gem 'omniauth-rails_csrf_protection'
追加したらGemをインストールする。
bundle install
Viewを編集できるようする。
rails generate devise:views users
config/initializers/devise.rb
# config.scoped_views = false
を config.scoped_views = true
に変更する。
vim app/views/users/shared/_links.html.erb
<%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider) %><br />
を
<%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), method: :post %><br />
に変更する。
次の記事はこちらです。
kawahara-ci.hatenablog.com