[Auth-1] 인증 코어 교체 + Devise 제거 + DB 마이그레이션

ID: a13af170-3220-4870-a2b9-5a24500b89a0

긴급 완료

## 목표
Devise를 제거하고 session[:user_id] 기반 직접 인증으로 전환. Gem/설정 제거 + DB 마이그레이션까지 완료.

## 작업 순서 (반드시 이 순서대로)

### Phase 1: 코어 교체
1. **ApplicationController 수정** (`app/controllers/application_controller.rb`)
- `before_action :authenticate_user!` 유지 (자체 구현으로 대체)
- private 메서드 추가:
```ruby
def current_user
@current_user ||= User.find_by(id: session[:user_id])
end
helper_method :current_user

def user_signed_in?
current_user.present?
end
helper_method :user_signed_in?

def authenticate_user!
unless user_signed_in?
redirect_to login_path, alert: "로그인이 필요합니다."
end
end
```
- `layout_by_resource` 메서드와 `layout :layout_by_resource` 제거 (devise_controller? 참조 없앰)

2. **SessionsController 생성** (`app/controllers/sessions_controller.rb`)
```ruby
class SessionsController < ApplicationController
skip_before_action :authenticate_user!, only: [:new]
layout "devise"

def new
redirect_to root_path if user_signed_in?
end

def destroy
reset_session
redirect_to login_path, notice: "로그아웃되었습니다."
end
end
```

3. **OmniauthController 수정** (`app/controllers/omniauth_controller.rb` - 새 위치)
- `app/controllers/users/omniauth_callbacks_controller.rb`를 `app/controllers/omniauth_controller.rb`로 이동
- Devise 상속 제거:
```ruby
class OmniauthController < ApplicationController
skip_before_action :authenticate_user!

def google_oauth2
handle_auth("Google")
end

def kakao
handle_auth("Kakao")
end

def failure
redirect_to login_path, alert: "로그인에 실패했습니다. 다시 시도해주세요."
end

private

def handle_auth(kind)
@user = User.from_omniauth(request.env["omniauth.auth"])
if @user.persisted?
session[:user_id] = @user.id
redirect_to root_path, notice: "#{kind}로 로그인되었습니다."
else
redirect_to login_path, alert: "#{kind} 로그인에 실패했습니다."
end
end
end
```

4. **라우트 수정** (`config/routes.rb`)
- `devise_for :users, ...` 제거
- 자체 라우트 추가:
```ruby
# 인증
get "login", to: "sessions#new", as: :login
delete "logout", to: "sessions#destroy", as: :logout

# OmniAuth 콜백
get "auth/:provider/callback", to: "omniauth#google_oauth2", constraints: { provider: "google_oauth2" }
get "auth/:provider/callback", to: "omniauth#kakao", constraints: { provider: "kakao" }
post "auth/:provider/callback", to: "omniauth#google_oauth2", constraints: { provider: "google_oauth2" }
post "auth/:provider/callback", to: "omniauth#kakao", constraints: { provider: "kakao" }
get "auth/failure", to: "omniauth#failure"
```

5. **User 모델 수정** (`app/models/user.rb`)
- `devise :database_authenticatable, :omniauthable, ...` 줄 전체 삭제
- `from_omniauth`에서 `Devise.friendly_token` 제거 (password 할당 불필요):
```ruby
def self.from_omniauth(auth)
where(provider: auth.provider, provider_id: auth.uid).first_or_create do |user|
user.email = auth.info.email
user.nickname = auth.info.name || auth.info.email.split("@").first
user.profile_image = auth.info.image
end
end
```

6. **뷰 이동**
- `app/views/devise/sessions/new.html.erb` → `app/views/sessions/new.html.erb`
- 뷰 내용에서 Devise 경로 수정:
- `user_google_oauth2_omniauth_authorize_path` → `/auth/google_oauth2`
- `user_kakao_omniauth_authorize_path` → `/auth/kakao`
- `new_user_session_path` → `login_path`

7. **사이드바 수정** - 로그아웃 링크 경로 확인
- `destroy_user_session_path` → `logout_path`
- method: :delete 유지

### Phase 2: OmniAuth 설정 이전
8. **OmniAuth 이니셜라이저 생성** (`config/initializers/omniauth.rb`)
```ruby
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2,
ENV["GOOGLE_CLIENT_ID"],
ENV["GOOGLE_CLIENT_SECRET"],
scope: "email,profile"

require_relative "../../lib/omniauth/strategies/kakao"
provider :kakao,
ENV["KAKAO_CLIENT_ID"],
ENV["KAKAO_CLIENT_SECRET"]
end

OmniAuth.config.allowed_request_methods = [:post, :get]
OmniAuth.config.silence_get_warning = true
```

### Phase 3: Devise 제거
9. **Gemfile에서 devise 제거** + `bundle install`
10. **config/initializers/devise.rb 삭제**
11. **app/views/devise/ 디렉토리 삭제** (views 이동 완료 후)
12. **app/controllers/users/ 디렉토리 삭제** (controller 이동 완료 후)

### Phase 4: DB 마이그레이션
13. **마이그레이션 생성** - Devise 전용 컬럼 제거:
```ruby
class RemoveDeviseColumnsFromUsers < ActiveRecord::Migration[8.1]
def change
remove_index :users, :reset_password_token
remove_column :users, :encrypted_password, :string
remove_column :users, :reset_password_token, :string
remove_column :users, :reset_password_sent_at, :datetime
remove_column :users, :remember_created_at, :datetime
end
end
```
14. `bin/rails db:migrate` 실행

## 주의사항
- UUID PK 사용 (`before_create :set_uuid` in ApplicationRecord)
- ERB 멀티라인 주석 안에 ERB 태그 금지 (SystemStackError)
- 모든 변경 후 서버가 기동 가능한지 확인
- test/ 디렉토리는 auth-test-dev가 담당 - 건드리지 말 것
- `bundle install` 실행 후 Gemfile.lock 업데이트 확인

첨부 이미지

이미지 추가 (Ctrl+V로 붙여넣기 또는 클릭)

JPEG, PNG, GIF, WebP / 최대 10MB

담당자: auth-app-dev
생성일: 2026년 03월 02일 05:32

활동 로그

  • 팀리드 상태 변경: 리뷰 → 완료

    2026년 03월 02일 05:56:20

  • A
    auth-app-dev schema_format :sql 전환 + structure.sql 생성 완료

    2026년 03월 02일 05:44:42

    상세 보기

    ## 변경 사항

    ### schema_format 전환
    - `config/application.rb`에 `config.active_record.schema_format = :sql` 추가
    - 손상된 `db/schema.rb` 삭제

    ### structure.sql 생성
    - `script/dump_structure.rb` 생성 (Ruby sqlite3 gem으로 DDL 추출)
    - `db/structure.sql` 생성 (16개 테이블 + 인덱스 + schema_migrations)
    - users 테이블 id 타입 수정 (`uuid` 누락 → 복원)

    ### sqlite3 CLI 부재 대응
    - `lib/tasks/db_structure.rake` 생성
    - `db:structure:load_via_ruby`: structure.sql을 Ruby로 로드
    - `db:structure:dump_via_ruby`: structure.sql을 Ruby로 덤프
    - sqlite3 CLI 없이도 DB 스키마 관리 가능

    ### 테스트 DB 준비 완료
    - `RAILS_ENV=test bin/rails db:structure:load_via_ruby`로 테스트 DB 정상 로드 확인
    - 16개 테이블 모두 생성됨

  • A
    auth-app-dev 상태 변경: 할 일 → 리뷰

    2026년 03월 02일 05:41:28

  • A
    auth-app-dev Devise 제거 + 자체 세션 관리 전환 완료

    2026년 03월 02일 05:41:27

    상세 보기

    ## 변경 사항

    ### Phase 1: ApplicationController 자체 인증
    - `app/controllers/application_controller.rb` 수정
    - `current_user` (session[:user_id] 기반), `user_signed_in?`, `authenticate_user!` 자체 구현
    - `layout_by_resource`, `devise_controller?` 의존 제거
    - `helper_method :current_user, :user_signed_in?` 선언

    ### Phase 2: 새 컨트롤러 생성
    - `app/controllers/sessions_controller.rb` 생성 (new, destroy)
    - `app/controllers/omniauth_controller.rb` 생성 (google_oauth2, kakao, failure + session[:user_id] 설정)

    ### Phase 3: 라우트 + 모델 + 뷰 수정
    - `config/routes.rb`: `devise_for` → 자체 라우트 (login, logout, auth/:provider/callback)
    - `app/models/user.rb`: `devise` 매크로 + `Devise.friendly_token` 제거
    - `app/views/sessions/new.html.erb` 생성 (devise 뷰에서 이동, 경로 수정)
    - 뷰 수정: profiles/show, shared/_sidebar, pages/home 내 Devise 헬퍼 → 새 경로

    ### Phase 4: OmniAuth 이전 + Devise 제거
    - `config/initializers/omniauth.rb` 생성 (OmniAuth::Builder 미들웨어 직접 설정)
    - `Gemfile`에서 `gem "devise"` 제거 + `bundle install`
    - 삭제: `config/initializers/devise.rb`, `app/views/devise/`, `app/controllers/users/`, `config/locales/devise.en.yml`

    ### Phase 5: DB 마이그레이션
    - `db/migrate/20260302150003_remove_devise_columns_from_users.rb` 생성
    - 제거된 컬럼: encrypted_password, reset_password_token, reset_password_sent_at, remember_created_at
    - 개발/테스트 DB 모두 마이그레이션 완료