[학습용] Rails5+heroku에서 Twitter 인증 구현: devise를 사용하지 않는 경우






비틀거렸지만 어떻게 든 인증까지 성공했기 때문에 메모

결론



여러 사이트의 코드를 관리하고 여러 번 실패했지만 소스 코드가 잘못되어 있지 않고 callback에 대한 설명이 잘못되었는지 궁금합니다.
성공적인 흐름과 코드를 기록해 둡니다.
※로컬에서도 Heroku에서도 동작 확인할 수 있었습니다.
callback에 로컬 주소 넣으면 할 수 있었습니다.

환경


Rails 5.2.1
Ruby  2.5.1
heroku

ubuntu16
IntelliJ IDEA

중요: 곤란한 경우



API keys 만들기 및 확인





Twitter에서 Consumer API keys 만들기
  • API key
  • API secret key

  • 이것이 없으면 만들 수 없습니다.
    열쇠를 틀리지 않도록 복사해 둡시다.
    Consumer API keys에서 좋습니다.

    고전하는 콜백 URL 확인





    Callback URL은 여러 곳에서 작성되었지만,
    API의 사양이 상당히 바뀔 것 같고 최신의 기술 방법이 아니면 에러로 연주됩니다.

    결국 2018/11/30 시점에서 성공한 방법은
    https://ドメイン名 + auth/twitter/callback が正解でした。
    

    Heroku 예: https://도메인 이름.herokuapp.com/auth/twitter/callback
    로컬 예: http://192.168.xx.yy:3000/auth/twitter/callback



    어쩌면 어디의 사이트의 예나 샘플 코드를 돈으로 해도 에러가 나오는 것은 이 기술이 다르기 때문에 연주된다고 생각합니다.

    앱 만들기: 여기에서 시작


    $ rails new twitterauthapp -d postgresql
    $ cd twitterauthapp
    $ bundle
    

    gem 추가


    gem 'omniauth'
    gem 'omniauth-twitter'
    

    env 파일 만들기



    /.env
    APP_ID = "API key を入れます"
    APP_SECRET = "API secret key を入れます"
    

    빈 파일을 만들고 위 내용을 설명합니다.
    Twitter에서 Consumer API keys 복사 페이스로 합니다.

    env를 게시하지 않는 설정



    /.gitignore
    /.env
    

    .gitignore에 위를 추가하면 Consumer API 키가 업로드되지 않습니다.

    omniauth.rb 만들기



    /config/initializers/omniauth.rb
    Rails.application.config.middleware.use OmniAuth::Builder do
      provider :twitter, ENV['APP_ID'], ENV['APP_SECRET']
    end
    

    파일을 새롭고 수동으로 만듭니다.
    빈 파일을 만들고 복사 OK.

    user 모델 만들기


    $ rails g model user provider:string uid:string user_name:string image_url:string
    

    devise를 사용하지 않는 버전입니다.
    이미 사용하고 있는 경우는 쓰는 방법이 다릅니다.

    작성한 user 모델에 작성



    /app/models/user.rb
    class User < ApplicationRecord
      def self.find_or_create_from_auth(auth)
        provider = auth[:provider]
        uid = auth[:uid]
        user_name = auth[:info][:user_name]
        image_url = auth[:info][:image]
    
        self.find_or_create_by(provider: provider, uid: uid) do |user|
          user.user_name = user_name
          user.image_url = image_url
        end
      end
    end
    

    신규 등록용 컨트롤러 작성


    $ rails g controller sessions
    

    /app/controllers/sessions_controller.rb
    class SessionsController < ApplicationController
      def create
        user = User.find_or_create_from_auth(request.env['omniauth.auth'])
        session[:user_id] = user.id
        flash[:notice] = "ユーザー認証が完了しました。"
        redirect_to root_path
      end
    
      def destroy
        reset_session
        flash[:notice] = "ログアウトしました。"
        redirect_to root_path
      end
    end
    

    도우미 메서드 추가



    /app/controllers/application_controller.rb
    class ApplicationController < ActionController::Base
      protect_from_forgery with: :exception
      helper_method :current_user, :logged_in?
    
      private
    
      def current_user
        return unless session[:user_id]
        @current_user ||= User.find(session[:user_id])
      end
    
      def logged_in?
        !!session[:user_id]
      end
    
      def authenticate
        return if logged_in?
        redirect_to root_path, alert: "ログインしてください"
      end
    end
    

    로그인 화면 만들기


    $ rails g controller home index
    

    우선, 로그인 할 수 있는 링크를 추가하므로 작성합니다.

    Twitter 로그인 링크 만들기



    /app/views/home/index.html.erb
    <% if session[:user_id]==nil %>
      <%= link_to "Twitterログイン", "/auth/twitter"%>
    <% else %>
      <%= link_to "Twitterログアウト", "/logout"%>
    <% end %>
    

    로그인용 링크.

    라우팅 설정



    /config/routes.rb
    Rails.application.routes.draw do
      get 'home/index'
      get '/auth/:provider/callback', to: 'sessions#create'
      get '/logout', to: 'sessions#destroy'
      root 'home#index'
    end
    

    로그인용 링크를 TOP으로 둡니다.

    로컬에서 화면 확인


    $ rails db:create
    $ rails db:migrate
    

    TOP 화면은 문제 없게 낼 수 있었습니다.
    로컬 환경에서도 동작을 확인할 수 있었습니다.

    여기서 로컬이 작동하지 않으면,
    로컬 용 Callback URL이 적절하지 않을까 생각합니다.

    ※rails db:create 는 하지 않아도 좋다고 생각합니다만, 자신의 환경에서는 몇번이나 써 지웠기 때문에
    데이터베이스가 남아 있거나 작성되지 않았기 때문에 작성했습니다.

    Heroku에 배포


    $ heroku create twitterauthapp 
    $ git init
    $ git add .
    $ git commit -am "test auth"
    $ git push heroku master
    
    $ heroku run rails db:migrate
    
    $ heroku config:set APP_ID=API key を入れます
    $ heroku config:set APP_SECRET=API secret key を入れます
    

    Heroku에 API key, API secret key를 등록합니다.
    $ heroku config
    

    API key, API secret key가 등록되어 있는지 확인할 수 있습니다.

    앱 URL을 결정한 후 매번 친숙한 명령입니다.
    Heroku에 API 키, API secret key 및 db:migrate를 잊지 마세요.

    인증 성공적인 화면





    이제 올린 화면의 URL을 클릭하면 Twitter 인증 화면이 나옵니다!

    좋은 웹페이지 즐겨찾기