Ruby on Rails Facebook Login API only mode
in Development on Rails
전반적인 설명과 Google Login방법은 Ruby on Rails Google Login API only mode에서 이미 했으니 그것을 참고하길 바란다.
이 글에서는 관련 코드만을 다루겠다.
1. FACEBOOK for Developers에 App 등록
https://developers.facebook.com로 들어가서 Facebook Login
App을 생성한다. Client OAuth Login
, Web OAuth Login
을 Yes로 설정한다. In development
상태를 On하면 다른 설정들은 특별히 없어도 정상동작한다. App ID
와 App Secret
을 확인한다. 아래에서 필요한 정보이다.
2. Gem Install
Gemfile에 아래 줄을 추가한다.
gem 'omniauth-facebook'
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
password
는 nullable로 설정하였다. 왜냐면 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 :facebook, ENV['FACEBOOK_APP_ID'], ENV['FACEBOOK_APP_SECRET']
end
.env
파일에 위에서 확인한 App ID
와 App Secret
를 각각 FACEBOOK_APP_ID
와 FACEBOOK_APP_SECRET
로 등록한다. 참고로 .env
파일을 적용하려면 dotenv-rails를 설치해야 한다.
4. Route 선언
routes.rb
파일에 아래 내용을 추가한다.
get 'auth/facebook/callback', to: 'auth#facebook'
5. Controller, Service 선언
auth_controller.rb
파일을 생성하여 아래와 같이 입력한다.
class AuthController < ApplicationController
def facebook
user = SocialAuthService.facebook(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.facebook(params)
apply(params, 'facebook')
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/facebook 를 Browser에서 실행하면 서버를 실행한 로그에 각 Model이 생성되는 SQL문을 볼 수 있으며, 화면에도 새로 생성된 사용자 정보를 볼 수 있다. 참고로 request.env['omniauth.auth']
정보를 확인해보고 싶다면 AuthController.facebook
의 내용을 render json: omniauth_params
로 수정을 하던지, 아니면 해당 method 안에서 binding.pry
를 걸어서 확인해보면 된다.
아래의 모양으로 되어 있다.
{
"provider"=>"facebook",
"uid"=>"1234567890",
"info"=>
{
"email"=>"seokjoon.yun@gmail.com",
"name"=>"Seok-joon Yun",
"image"=>"http://graph.facebook.com/v4.0/4368718413198581/picture"
},
"credentials"=>
{
"token"=>"xxxx.xxxxxxxxcxcxcxcxcxcxcxcxcxcxcxcxxcxc",
"expires_at"=>1611636890,
"expires"=>true
}
}
마치며…
위에서 소개한 방법을 적용한 예제코드는 아래 Link에서 확인이 가능하다.
https://github.com/DevStarSJ/backend_boilerplates/tree/master/rails
이로서 Facebook Login
에 대한 안내는 마치겠다.
다른 Social Login의 방법은 아래에서 확인이 가능하다.
- Ruby on Rails Google Login API only mode
- Ruby on Rails Facebook Login API only mode
- Ruby on Rails Naver Login API only mode
- Ruby on Rails Kakao Login API only mode
- Ruby on Rails Line Login API only mode
이 글이 도움이 되셨다면 공감 및 광고 클릭을 부탁드립니다 :)