LoginSignup
3
1

More than 1 year has passed since last update.

Rails7+omniauth-twitterでtwitterログイン

Last updated at Posted at 2022-10-24

はじめに

現在開発している子育て情報サービス『コノタメ』にて、twitterのAPIを利用してログインする機能を実装しました。
手順を忘れないように記録しておきたいと思います。

環境

  • Ruby 3.1.2
  • Ruby on Rails 7.0.3
  • 【gem】 sorcery 0.16.4
  • 【gem】 turbo-rails 1.1.1
  • omniauth-twitter 1.4.0

※ sorceryは利用しておりますが、sorceryのexternalモジュールは使用していません。

前提

Simple Password Authenticationにて、メールアドレス認証機能は実装済み

手順

1. Twitter APIの登録

Developer Platformで、API申請をします。
これはたくさんの記事がありますので、割愛。
こちらの記事とか、とても参考になります。
注意点は、Callback URIをきちんと入力しておくこと、アクセスレベルを"Essential"ではなく、"Elevated"にしておくこと。

2. Gemのインストール

ここから先は、
こちらの記事コピペ参考に。

# Gemfile

gem 'omniauth'
gem 'omniauth-twitter'
gem "omniauth-rails_csrf_protection"
gem 'dotenv-rails'

そしてbundle install

gem "omniauth-rails_csrf_protection"を入れるのは、下の記事を読みまして。

3. APIキーの登録

Consumer KeysのAPI Key and Secretを.envファイルに登録します。(.envファイルは.gitignoreに入れておく。)

# .env

TWITTER_KEY = 自分のAPI Key
TWITTER_SECRET = 自分のSecret

今回は、herokuにデプロイしていますので、herokuのSettings > Config VarsにもこちらのKeyやSecretを登録しておきます。

4. Userモデル追記

# migrationファイル

class SorceryCore < ActiveRecord::Migration[7.0]
  def change
    create_table :users do |t|
      t.string :email,            null: false
      t.string :name,                         null: false
      t.string :crypted_password
      t.string :salt

      t.timestamps                null: false
    end
  end
end

既にこのような形でUserモデルが作成されているので、以下をモデルファイルに追記。

# user.rb

class User < ApplicationRecord
  def self.find_or_create_from_auth(auth)
    uid = auth[:uid]
    name = auth[:info][:name]
    if auth[:info][:email].present?
      email = auth[:info][:email]
    else
      email = uid + '(好きなようにダミーを作る)' #入力しないとvalidationのため、user登録されないので、適当に作成。
    end

    self.find_or_create_by(email: email) do |user|
        user.name = name
        user.email = email
        user.password = (好きなように式などでダミーを作る) #入力しないとvalidationのため、user登録されないので、適当に作成。
        user.password_confirmation = user.password
    end
  end
end

5. Sessionコントローラー作成

# app/controllers/session_controller.rb

class SessionsController < ApplicationController
  skip_before_action :require_login

  def create
    @user = User.find_or_create_from_auth(request.env['omniauth.auth'])
    reset_session
    auto_login(@user)
    redirect_to root_path, notice: 'ログインしました'
  end

  def failure
    redirect_to root_url, notice: 'ログインに失敗しました'
  end
end

application_controller.rbに、before_action :require_loginを設定しているので、skip_before_action :require_loginを入れておかないと、ログインボタンを押しても、「ログインしてください」とだけメッセージがでてきて、一向にログインできません。
auto_login(user)はsorceryのメソッドです。

# config/routes.rb

Rails.application.routes.draw do
  get '/auth/:provider/callback', to: 'sessions#create'
  get '/auth/failure', to: 'sessions#failure'
end

ログアウトはsorceryで実装済みですので、今回は省いております。

6. ログインリンク作成

<%= button_to '/auth/twitter', method: :post, data: { turbo: false } do %><%= image_tag "/assets/sign-in-with-twitter-gray.png.twimg.1920.png" %><% end %>

実はここが一番苦労したところです。
ボタンを押しても押しても、画面遷移しないわけです。
何日も悩んでいたところに出会った記事が、こちら!!
ふむふむ、、、rails7では、link_toのときに、method: :postが効かないことは知っていたので、button_toを使ってはいました。
しかし、さらに、data: { turbo: false }が必要だったようです!!
turbo-railsを利用されている方はご注意ください。

おわりに

最初、sorceryのexternalモジュールを試してみたのですが、そうしたらAuthenticationデータがログインごとに作成されて困ってしまい、結局諦めることになりました。続いて、今回のomniauthを使うことにしたのですが、401エラーが出たり、302で終了したりして、何日も悩み、諦めかけていたのですが、たくさんの記事に救われ、今回ログイン機能を実装することができました!
この記事がどなたかのお役に立てればうれしいです。
また、何かご指摘がございましたら、コメントいただけるとうれしいです。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1