【Rails6 × React】 devise_auth_token에서의 SNS 인증시 최초 로그인의 경우에만 특정 처리를 촉구한다

환경



API
  • Rails6.0

  • 전면
  • React

  • 목적



    Omniauth를 이용한 SNS 인증으로 사용자 등록으로 처음 로그인할 때 SNS상의 계정 정보에서 일부 변경하거나 추가 정보의 입력을 촉구하고 싶다.
    devise_auth_token을 사용하고 있지만, devise에서도 기본은 똑같이 설계해도 좋다고 생각한다.

    구현 방법



    ①users 테이블에 Trackable계의 컬럼을 추가한다


    class AddColumnsToUsers < ActiveRecord::Migration[6.0]
      def change
        add_column :users, :sign_in_count, :integer, default: 0, null: false
        add_column :users, :current_sign_in_at, :datetime
        add_column :users, :last_sign_in_at, :datetime
        add_column :users, :current_sign_in_ip, :string
        add_column :users, :last_sign_in_ip, :string
      end
    end
    

    이러한 컬럼을 추가. 위에서 순서대로
  • 로그인 횟수
  • 현재 로그인 한 날짜와 시간
  • 마지막으로 로그인한 날짜와 시간
  • 현재 로그인 소스 IP 주소
  • 마지막으로 로그인했을 때의 로그인 원 IP 주소

  • 정보가 있습니다.

    ②models/user.rb에서 trackable을 설정


    class User < ActiveRecord::Base
      # Include default devise modules. Others available are:
      # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
      devise :database_authenticatable, :registerable,  :trackable, #←これ
             :recoverable, :rememberable, :validatable, :omniauthable, omniauth_providers: [:twitter]
    

    모델에도 설정이 필요. 반대로 말하면 이것만으로 로그인시에 마음대로 컬럼에 값이 들어간다.

    ③omniauth에서의 인증시에 유저가 첫회 로그인인가 어떤가를 판정한다


    def render_data_or_redirect(message, data, user_data = {})
      # 初回ログイン時にはcookieに情報をセット。Oauth認証後ユーザー情報の編集ページに飛ばす
      cookies[:first_session] = { value: true, path: root_path, expres: 10.minutes }  if @resource.sign_in_count == 0 
    

    devise_auth_token에서 omniauth_callbacks 컨트롤러로 사용자가 인증 할 수있는 경우
    render_data_or_redirect 메소드가 호출된다. 이 방법으로 앱 측 페이지로 반환하기 직전에
    저장된 사용자의 sign_in_count가 0인 경우 쿠키에 first_session이라는 값을 넣는다. 마감 기한은 10 분입니다.

    ④ 프런트 측에서 쿠키에서 첫 로그인의 tmp 데이터를 취득한다


    class App extends React.Component {
    
      componentDidMount() {
        const cookies = new Cookies();
        // ユーザー認証が済んでいる場合
        if (authToken) { 
          if (cookies.get('first_session')) {
            // 実際にはユーザー情報編集ページに飛ばす処理を入れる。次のブランチで
            alert('初回ログイン')
          }
          // 中略
          return authToken
        } else {
          return null
        }
      }
    

    이번에는 루트 구성 요소의 앱으로 로그인했는지 여부를 판단하기 때문에,
    거기에 쿠키 안에 first_session이 존재하고 있는지 어떤지를 판정하는 조건식을 구현.
    쿠키를 읽는 라이브러리로는 사전에 범용 쿠키가 도입되었습니다.
    npm install universal-cookie
    

    ⑤ 2번째 이후 로그인 시 쿠키 tmp 데이터 삭제



    tmp데이터의 유효기간이 10분이나 되어 있기 때문에, 10분 이내에 2회 로그인되는 것도 상정해 2회째 이후의 로그인에서는
    쿠키의 데이터를 삭제하도록 했다.
    # 2回目以降のログイン時にはfirst_sessionのクッキーデータを削除
    cookies.delete(:first_session, path: root_path) if cookies[:first_session]
    

    거동



    지금까지의 흐름에서 거동은 다음과 같다.


    감상



    생각보다 간단하게 생겼다.
    Trackable계의 칼럼 제대로 사용한 적이 없었기 때문에 이런 사용법을 할 수 있을까, 라고 감동했다.
    쿠키를 사용하여 조건 분기하고 있으므로 보안적으로 어떻습니까? 라든지는 있지만 일단 두어 둔다.

    좋은 웹페이지 즐겨찾기