SNS 로그인 구현 예제
이 글에서는 Rails 환경에서 SNS 로그인을 구현하는 방법을 예제 코드와 함께 자세히 안내해 드립니다.
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :trackable, :rememberable, :validatable, :omniauthable
validates :name, presence: true, :length => { :maximum => 7 }
# SNS 로그인
has_one :identity, dependent: :destroy
# 번개
has_many :events, dependent: :destroy
# 번개 참가신청
has_many :user_events, dependent: :destroy
# 댓글
has_many :comments, dependent: :destroy
# 댓글 좋아요
has_many :likes, dependent: :destroy
# 알림
has_many :notifications, dependent: :destroy
# 팔로우
has_many :follower_relations, foreign_key: "followed_id", class_name: "Follow"
has_many :followers, through: :follower_relations, source: :follower, dependent: :destroy
has_many :following_relations, foreign_key: "follower_id", class_name: "Follow"
has_many :followings, through: :following_relations, source: :followed, dependent: :destroy
# 메시지
has_many :messages, dependent: :destroy
# 신고
has_many :report, dependent: :destroy
# sms
has_many :sms_messages
before_save :set_location
mount_uploader :image, UserUploader
acts_as_mappable :default_units => :kms,
:default_formula => :sphere,
:distance_field_name => :distance,
:lat_column_name => :lat,
:lng_column_name => :lng
enum grade: [:normal, :admin]
enum gender: [:not_choose, :man, :woman]
def self.find_for_oauth(auth, signed_in_resource = nil)
identity = Identity.find_for_oauth(auth)
user = signed_in_resource ? signed_in_resource : identity.user
if user.nil?
auth_email = auth.info.email
user = User.where(email: auth_email).first
unless user.present?
if auth.info.email.nil?
if auth.provider == "kakao"
user = User.new(
email: "kakaoUser@#{auth.uid}.com",
remote_image_url: auth.info.image,
name: auth.info.name,
password: Devise.friendly_token[0,20]
)
elsif auth.provider == "facebook"
user = User.new(
email: "facebookUser@#{auth.uid}.com",
remote_image_url: auth.info.image,
name: auth.info.name,
password: Devise.friendly_token[0,20]
)
end
else
user = User.new(
email: auth.info.email,
remote_image_url: auth.info.image,
name: auth.info.name,
password: Devise.friendly_token[0,20]
)
end
# user.skip_confirmation! # 이메일 인증이 있는 경우 인증을 자동 완료해줌
user.save!
end
end
if identity.user != user
identity.user = user
identity.save
end
user #user 리턴
end
def set_location
if self.en_address.present?
results = HTTParty.get("https://maps.googleapis.com/maps/api/place/textsearch/json?input=#{self.en_address}&inputtype=textquery&key=AIzaSyATof4VolMTPTEz78KgGKAOVAzlFzO3QmY")
result_hash = JSON.parse(results.body)
if result_hash["results"] == [] ## 검색결과가 비어있는 경우
splited_num = self.en_address.split(',').size
remade_adress = self.en_address.split(',')[1..splited_num].join
results = HTTParty.get("https://maps.googleapis.com/maps/api/place/textsearch/json?input=#{remade_adress}&inputtype=textquery&key=AIzaSyATof4VolMTPTEz78KgGKAOVAzlFzO3QmY")
result_hash = JSON.parse(results.body)
unless result_hash["results"] == []
self.lat = result_hash["results"][0]["geometry"]["location"]["lat"]
self.lng = result_hash["results"][0]["geometry"]["location"]["lng"]
end
else
self.lat = result_hash["results"][0]["geometry"]["location"]["lat"]
self.lng = result_hash["results"][0]["geometry"]["location"]["lng"]
end
else
self.lat = 0
self.lng = 0
end
end
def self.gender_options
options = [['선택안함', "not_choose"], ['남자', "man"], ['여자', "woman"]]
options.unshift(["성별을 선택해주세요.", -1])
options
end
def is_apply(event)
UserEvent.find_by(user: self, event: event, _type: "apply").present?
end
def is_keeping(event)
UserEvent.find_by(user: self, event: event, _type: "keeping").present?
end
def is_follower(user)
self.followings.include?(user)
end
def is_like(comment)
Like.find_by(user: self, comment: comment).present?
end
def is_waiting(event)
UserEvent.find_by(user: self, event: event, _type: "apply", _state: "waiting").present?
end
def is_accept(event)
UserEvent.find_by(user: self, event: event, _type: "apply", _state: "accept").present?
end
def allow(event)
user_event = UserEvent.find_by(user: self, event: event, _type: "apply", _state: "waiting")
if user_event.present?
user_event._state = "accept"
user_event.save
end
end
def unallow(event)
user_event = UserEvent.find_by(user: self, event: event, _type: "apply", _state: "accept")
if user_event.present?
user_event._state = "waiting"
user_event.save
end
end
def rooms
(Room.where(user1: self) + Room.where(user2: self)).sort_by(&:created_at).reverse
end
def not_read_messages
Message.includes(:room).where.not(user: self).where(is_check: false, rooms: {user1: self}) + Message.includes(:room).where.not(user: self).where(is_check: false, rooms: {user2: self})
end
end
이것도 읽어보세요