railsでtwitter認証する

#twitter developerの設定は省く

```:コンソール
$ rails _5.1.6_ new twitter-auth
```

```:Gemfile
source 'https://rubygems.org'

gem 'rails',        '5.1.6'
gem 'puma',         '3.9.1'
gem 'sass-rails',   '5.0.6'
gem 'uglifier',     '3.2.0'
gem 'coffee-rails', '4.2.2'
gem 'jquery-rails', '4.3.1'
gem 'turbolinks',   '5.0.1'
gem 'jbuilder',     '2.7.0'

gem 'omniauth'
gem 'omniauth-twitter'
gem 'dotenv-rails' #環境変数を簡単に利用できるgem


group :development, :test do
  gem 'sqlite3', '1.3.13'
  gem 'byebug',  '9.0.6', platform: :mri
end

group :development do
  gem 'web-console',           '3.5.1'
  gem 'listen',                '3.1.5'
  gem 'spring',                '2.0.2'
  gem 'spring-watcher-listen', '2.0.1'
end

group :test do
  gem 'rails-controller-testing', '1.0.2'
  gem 'minitest',                 '5.10.3'
  gem 'minitest-reporters',       '1.1.14'
  gem 'guard',                    '2.13.0'
  gem 'guard-minitest',           '2.4.4'
end

group :production do
  gem 'pg', '0.20.0'
end

# Windows環境ではtzinfo-dataというgemを含める必要があります
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
```

```:コンソール
$ bundle install
$ rails generate controller Users home

$ rails g model user provider:string uid:string username:string image_url:string 
$ rails db:migrate
$ rails db:migrate RAILS_ENV=test

$ touch .env
$ touch config/initializers/omniauth.rb
```

```:.env
TWITTER_CONSUMER_KEY    = '**************'
TWITTER_CONSUMER_SECRET = '**************'
```

```:config/secrets.yml
default_twitter: &default_twitter
  twitter_api_key: <%= ENV["TWITTER_CONSUMER_KEY"] %>
  twitter_api_secret: <%= ENV["TWITTER_CONSUMER_SECRET"] %>

development:
  secret_key_base: 
//事前に数値が入っている
  <<: *default_twitter

test:
  secret_key_base: 
//事前に数値が入っている
  <<: *default_twitter

production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
  twitter_api_key: <%= ENV["TWITTER_CONSUMER_KEY"] %>
  twitter_api_secret: <%= ENV["TWITTER_CONSUMER_SECRET"] %>
```

以下を追加

```:gitignore
/.env
```

```ruby:config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :twitter, ENV['TWITTER_CONSUMER_KEY'], ENV['TWITTER_CONSUMER_SECRET']
end
```

```app/models/user.rb
class User < ApplicationRecord

  def self.find_or_create_from_auth_hash(auth_hash)
   provider = auth_hash[:provider]#providerはどのサービスで認証したのかを見分けるもの
   uid = auth_hash[:uid]
   name = auth_hash[:info][:name]
   image_url = auth_hash[:info][:image]

   #find_or_create_by()は()の中の条件のものが見つければ取得し、なければ新しく作成するというメソッド
   self.find_or_create_by(provider: provider,uid: uid) do |user|
     user.username = name
     user.image_url = image_url
   end
  end
end
```


```ruby:app/controllers/users_controller.rb
class UsersController < ApplicationController
  def home
  end

  def create
     user = User.find_or_create_from_auth_hash(request.env['omniauth.auth'])#request.env['omniauth.auth']はTwitter認証で得た情報を格納するもの
     if user
       session[:user_id] = user.id
       session[:user_name] = user.username
       redirect_to root_path, notice: "ログインしました。"
     else
       redirect_to root_path, notice: "失敗しました。"
     end
   end
end
```

```ryby:config/routes.rb
Rails.application.routes.draw do
  get 'users/home'
  get 'auth/:provider/callback' => 'users#create'#このpathを通して認証が行われる。
  root 'users#home'
end
```

```eruby:app/views/users/home.html.erb
<h1>Users#home</h1>
<p>Find me in app/views/users/home.html.erb</p>

<%= link_to 'Twitterでログイン', '/auth/twitter' %>

<%= session[:user_name] %>
```

```:コンソール
rails s
```

# 参照
[https://qiita.com/keiya01/items/c96a0393c76f5560ee41](https://qiita.com/keiya01/items/c96a0393c76f5560ee41)

##追記
herokuにあげてからやる事
1. twitter developperにアップしたherokuのドメインを追加しておく
2. 以下のコマンドで環境変数を与えておく

```console:登録
$ heroku config:set TWITTER_CONSUMER_KEY="*********************************"
$ heroku config:set TWITTER_CONSUMER_SECRET="***********************************"
```

***の所はtwitter developperで貰った値を入れる。

```console:確認
$ heroku config
```
###ぼやき
ダブルクオーテーションで囲えばいいものをシングルクオーテーションにしていたため、うまくいかず、毛根を犠牲にしました。

```console:失敗例(登録はできるがtwitter認証はできない)
$ heroku config:set TWITTER_CONSUMER_KEY='*********************************'
$ heroku config:set TWITTER_CONSUMER_SECRET='***********************************'
```