사용버전
ruby "3.1.3"
gem "rails", "~> 7.0.3", ">= 7.0.3.1"
1. user 모델 생성
rails g model KakaoUser
- db\migrate\20230329053439_create_kakao_users.rb 해당 경로 파일에 아래 코드 입력 (모델 만들면 자동 생성됨)
class CreateKakaoUsers < ActiveRecord::Migration[7.0]
def change
create_table :kakao_users do |t|
t.string :user_id
t.string :email
t.string :nickname
t.string :remember_token
t.timestamps
end
end
end
- 모델 만들어 줬으면 아래 명령어로 파일 업데이트
rake db:migrate
- app\models\kakao_user.rb 해당 경로 파일에 아래 코드 입력
class KakaoUser < ActiveRecord::Base
before_save { self.user_id = user_id.downcase }
before_create :create_remember_token
def KakaoUser.new_remember_token
SecureRandom.urlsafe_base64 # 키 랜덤 생성
end
def KakaoUser.encrypt(token)
Digest::SHA1.hexdigest(token.to_s) # 키 암호화
end
private
def create_remember_token
self.remember_token = KakaoUser.encrypt(KakaoUser.new_remember_token) # 토큰 정보 저장
end
end
2. 필요한 컨트롤러 생성
rails g controller KakaoSessions
2-1 컨트롤러 파일 작성
class KakaoSessionsController < ApplicationController
include ApplicationHelper
def new
end
def create
user = KakaoUser.find_by(user_id: params[:user_id].downcase)
if user
sign_in user
render json: { success: true, message: "로그인 성공" }
else
# 새로운 사용자 생성
@user = KakaoUser.new
@user.user_id = params[:user_id]
@user.email = params[:email]
@user.nickname = params[:nickname]
# 사용자 정보 저장
if @user.save
sign_in @user
puts "회원가입 성공"
render json: { success: true, message: "회원가입 성공" }
else
puts "회원가입 실패"
render json: { success: false, message: "회원가입 실패" }
end
end
end
def destroy
sign_out
redirect_to root_url
end
end
3. 라우트 설정
Rails.application.routes.draw do
resources :users
resources :sessions, only: [:new, :create, :destroy]
root 'sessions#new'
match '/signup', to: 'users#new', via: 'get'
match '/signin', to: 'sessions#new', via: 'get'
match '/signout', to: 'sessions#destroy', via: 'delete'
post '/signout', to: 'sessions#destroy'
end
4. view 생성
<% if signed_in? %>
<a id="kakao-login-btn"></a>
<%= button_to "로그아웃", signout_path, method: "delete" %>
<% else %>
<a id="kakao-login-btn"></a>
<% end %>
<%= form_tag "/kakao_sessions", id: "my-form" do %>
<%= hidden_field_tag :user_id %>
<%= hidden_field_tag :email %>
<%= hidden_field_tag :nickname %>
<%= hidden_field_tag :authenticity_token, value: form_authenticity_token %>
<%= submit_tag "Sign in", style: "display: none" %>
<% end %>
<button class="api-btn" onclick="unlinkApp()">앱 탈퇴하기</button>
//JS
<script>
function unlinkApp() {
Kakao.API.request({
url: '/v1/user/unlink',
success: function(res) {
alert('success: ' + JSON.stringify(res))
},
fail: function(err) {
alert('fail: ' + JSON.stringify(err))
},
})
}
Kakao.init('발급받은 JS KEY');
console.log(Kakao.isInitialized());
Kakao.Auth.createLoginButton({
container: '#kakao-login-btn',
success: function(authObj) {
Kakao.API.request({
url: '/v2/user/me',
success: function(result) {
const formData = new FormData();
formData.append('user_id', result.id);
formData.append('email', result.kakao_account.email);
formData.append('nickname', result.properties['nickname']);
fetch('/kakao_sessions', {
method: 'POST',
body: formData,
headers: {
'X-CSRF-Token': '<%= form_authenticity_token %>'
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
// 로그인 성공 시 처리
location.href = "/";
} else {
// 로그인 실패 시 처리
}
});
},
fail: function(error) {
alert(
'login success, but failed to request user information: ' +
JSON.stringify(error)
);
}
});
},
fail: function(err) {
alert('failed to login: ' + JSON.stringify(err));
}
});
</script>
5. 헬퍼 작성
module KakaoSessionsHelper
# 로그인시 세션 토큰을 만들고 쿠키에 저장
def sign_in(user)
remember_token = KakaoUser.new_remember_token
cookies.permanent[:remember_token] = remember_token
user.update_attribute(:remember_token, KakaoUser.encrypt(remember_token))
self.current_user = user
end
# 로그인했는지 여부를 확인
def signed_in?
!current_user.nil?
end
# 이후의 페이지에서 세션토큰을 위해서 사용자 정보를 가져온다.
def current_user=(user)
@current_user = user
end
# 쿠키에 저장된 토큰을 가져와서 사용한다. 이 토큰을 이용해서 사용자 정보도 가져온다.
def current_user
remember_token = KakaoUser.encrypt(cookies[:remember_token])
@current_user ||= KakaoUser.find_by(remember_token: remember_token)
end
# 로그 아웃
def sign_out
self.current_user = nil
cookies.delete(:remember_token)
end
end
6. app\controllers\application_controller.rb 작성
- application_controller에 session helper include (어플리케이션 전체에서 사용할 것이기 때문에)
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
include KakaoSessionsHelper
helper_method :signed_in?, :current_user
private
def check_signed_in
redirect_to 'http://39.120.151.57:3000/signin' unless signed_in?
end
end
7. 로그인 체크하고싶은 컨트롤러에 아래와 같이 작성
before_action :check_signed_in
'Ruby on Rails' 카테고리의 다른 글
📚 [Ruby on Rails] 회원정보 수정 구현 ( f. 다음 주소 API ) (0) | 2023.04.06 |
---|---|
📚 [Ruby on Rails] Carrierwave로 이미지 여러장 업로드 구현하기 (0) | 2023.02.24 |
📚 [Ruby on Rails] 라우트, 라우팅 설정 (0) | 2023.01.25 |
📚 [Ruby on Rails] 개발 폴더 생성, 컨트롤러 생성 - window, vscode (0) | 2023.01.20 |
댓글