Ruby on Rails Naver Login API only mode


전반적인 설명과 Google Login방법은 Ruby on Rails Google Login API only mode에서 이미 했으니 그것을 참고하길 바란다.

이 글에서는 관련 코드만을 다루겠다.

1. NAVER for Developers에 App 등록

https://developers.naver.com로 들어가서 Application 등록을 하면서 사용 API에서 네아로(네이버 아이디로 로그인)을 선택한다. API 설정 탭으로 가서 서비스 URLhttp://localhost:3000를 입력하고, 네이버아이디로로그인 Callback URLhttp://localhost:3000/auth/naver/callback를 입력한다. 다시 개요 탭으로 와서 Client IDClient Secret을 확인한다. 아래에서 필요한 정보이다.

2. Gem Install

Gemfile에 아래 줄을 추가한다.

gem 'omniauth-naver'

Bundle을 실행하여 Install을 한다.

bundle install

2. Model 생성

필자의 경우 User Model과 SocialAuth Model을 분리하였다. 왜냐면 1명의 User에게 여러 Social Login을 가능하게 하기 위해서이다.

2.1 User Model 생성

rails g model User 를 실행하여 Migration 파일을 수정한다.

class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :email, null: false
      t.string :password_digest

      t.timestamps
    end
  end
end

passwordnullable로 설정하였다. 왜냐면 password가 없는 경우 Social Login만을 허용하기 위해서다. 하지만 Model에서 Null Check를 하므로 validation을 하지 않는 것으로 선언해야 한다.

  • user.rb
    class User < ApplicationRecord
    include ActiveModel::SecurePassword
    has_secure_password validations: false
    end
    

rails db:migrate 를 실행하여 Model을 생성한다.

2.2 SocialAuth Model 생성

rails g model SocialAuth를 실행하여 Migration 파일을 생성 후

class CreateSocialAuths < ActiveRecord::Migration[6.0]
  def change
    create_table :social_auths do |t|
      t.string :provider, null: false
      t.string :uid, null: false
      t.string :first_name
      t.string :last_name
      t.string :email
      t.string :photo
      t.references :user, null: false, foreign_key: false

      t.timestamps
    end
  end
end

위 내용과 같이 수정한다.

  • social_auth.rb
    class SocialAuth < ApplicationRecord
    belongs_to :user
    end
    

Model 파일을 수정한 뒤 rails db:migrate 를 실행하여 Model을 생성한다.

3. Initialize 선언

config/initializers/omniauth.rb 파일을 생성하여 아래와 같이 입력한다.

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :naver, ENV['NAVER_KEY'], ENV['NAVER_SECRET']
end

.env 파일에 위에서 확인한 App IDApp Secret를 각각 NAVER_KEYNAVER_SECRET로 등록한다. 참고로 .env파일을 적용하려면 dotenv-rails를 설치해야 한다.

4. Route 선언

routes.rb파일에 아래 내용을 추가한다.

 get 'auth/naver/callback', to: 'auth#naver'

5. Controller, Service 선언

auth_controller.rb 파일을 생성하여 아래와 같이 입력한다.

class AuthController < ApplicationController
  def naver
    user = SocialAuthService.naver(omniauth_params)
    render json: user
  end

  private
  def omniauth_params
    request.env['omniauth.auth'].except('extra').to_h
  end
end

참고로 인증받은 구글에서의 profile정보는 request.env['omniauth.auth']에서 확인이 가능하다. 예제에서는 User Model을 그대로 response해주는 것으로 해 놓았다. 실제 사용할때는 생성되거나 찾은 사용자 정보에서 JWT Token등을 생성해서 전달해 준다던지, request.env['omniauth.auth']안에 있는 token을 그대로 사용하는 방법이 있겠다.

social_auth_service.rb 파일을 생성하여 아래와 같이 입력한다.

class SocialAuthService
  def self.naver(params)
    apply(params, 'naver')
  end

  def self.apply(params, provider)
    return nil unless params["provider"].present? && params["uid"].present? && params["info"].present?
    return nil unless params["provider"].include?(provider)

    social_auth = initialize(params, provider)
    social_auth.user
  end

  def self.initialize(params, provider)
    SocialAuth.where(provider: provider, uid: params["uid"]).first_or_create do |auth|
      auth.provider = provider
      auth.uid = params["uid"]
      auth.email = params["info"]["email"]
      auth.first_name = params["info"]["first_name"] ||  params["info"]["name"]
      auth.last_name = params["info"]["last_name"]
      auth.photo = params["info"]["image"]
  
      link_user(auth)
    end
  end

  def self.link_user(auth)
    return if auth.user_id.present?

    user = User.find_by(email: auth.email)
    user = User.create(email: auth.email) if user.blank?
    auth.user = user
  end
end

.first_or_create는 앞에 조건에 만족하는 첫번째 instance를 반환하거나 없다면 block에 선언한대로 새로 생성을 한다. 여기서 찾거나 새로 생성한 SocialAuth에서 전달받은 email정보를 가지고 User를 검색한 후, 있으면 그 User와 연결을 하고 없다면 User를 새로 생성한다. 이 부분 역시 .first_or_create를 사용해도 된다.

6. 실행 및 확인

이제 서버를 실행해서 확인해보자.

rails s

로 서버를 실행한 다음 http://localhost:3000/auth/naver 를 Browser에서 실행하면 서버를 실행한 로그에 각 Model이 생성되는 SQL문을 볼 수 있으며, 화면에도 새로 생성된 사용자 정보를 볼 수 있다. 참고로 request.env['omniauth.auth'] 정보를 확인해보고 싶다면 AuthController.naver의 내용을 render json: omniauth_params로 수정을 하던지, 아니면 해당 method 안에서 binding.pry를 걸어서 확인해보면 된다.

아래의 모양으로 되어 있다.

{
  "provider"=>"naver",
  "uid"=>"1234567890",
  "info"=>
  {
    "name"=>"윤석준",
    "email"=>"seokjoon.yun@gmail.com",
    "gender"=>"male",
    "image"=>"https://phinf.pstatic.net/contact/20160828_277/1472389971532m2ha0_JPEG/image.jpg",
    "nickname"=>"별빛"
  },
  "credentials"=>
  {
    "token"=>"xcxcxcxcxcxcxcxcx",
    "refresh_token"=>"xcxcxcxcxcxcxcxcx",
    "expires_at"=>1606466104,
    "expires"=>true
  }
}

마치며…

위에서 소개한 방법을 적용한 예제코드는 아래 Link에서 확인이 가능하다.

https://github.com/DevStarSJ/backend_boilerplates/tree/master/rails

이로서 Naver Login에 대한 안내는 마치겠다.

다른 Social Login의 방법은 아래에서 확인이 가능하다.


이 글이 도움이 되셨다면 공감 및 광고 클릭을 부탁드립니다 :)