From 1f7547b40fe476dcf3f98e94b76ac0e4e47ff30b Mon Sep 17 00:00:00 2001 From: topi0247 Date: Sat, 25 Apr 2026 15:23:21 +0900 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20Cookie=E5=80=A4=E3=81=8CArray?= =?UTF-8?q?=E3=81=AB=E3=81=AA=E3=82=8B=E5=95=8F=E9=A1=8C=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=20(#18)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `cookies[key]` → `request.cookies[key]` に変更(flat string hashで返るためArray問題を回避) - `before_action` → `prepend_before_action` に変更(DeviseTokenAuthのset_user_by_tokenより先に実行) - OmniauthCallbacksControllerでset_auth_headers_from_cookiesをskip Co-Authored-By: Claude Sonnet 4.6 --- back/app/controllers/application_controller.rb | 10 +++++----- .../controllers/auth/omniauth_callbacks_controller.rb | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/back/app/controllers/application_controller.rb b/back/app/controllers/application_controller.rb index eef3bba..d7e3630 100644 --- a/back/app/controllers/application_controller.rb +++ b/back/app/controllers/application_controller.rb @@ -1,14 +1,14 @@ class ApplicationController < ActionController::API include ActionController::Cookies include DeviseTokenAuth::Concerns::SetUserByToken - before_action :set_auth_headers_from_cookies + prepend_before_action :set_auth_headers_from_cookies private def set_auth_headers_from_cookies - request.headers['access-token'] ||= cookies['access-token'] - request.headers['client'] ||= cookies['client'] - request.headers['uid'] ||= cookies['uid'] - request.headers['expiry'] ||= cookies['expiry'] + request.headers['access-token'] ||= request.cookies['access-token'] + request.headers['client'] ||= request.cookies['client'] + request.headers['uid'] ||= request.cookies['uid'] + request.headers['expiry'] ||= request.cookies['expiry'] end end diff --git a/back/app/controllers/auth/omniauth_callbacks_controller.rb b/back/app/controllers/auth/omniauth_callbacks_controller.rb index 23ebeb7..c017adf 100644 --- a/back/app/controllers/auth/omniauth_callbacks_controller.rb +++ b/back/app/controllers/auth/omniauth_callbacks_controller.rb @@ -1,4 +1,5 @@ class Auth::OmniauthCallbacksController < DeviseTokenAuth::OmniauthCallbacksController + skip_before_action :set_auth_headers_from_cookies def redirect_callbacks user = User.from_omniauth(request.env['omniauth.auth']) From 8c559c1c31cc09a0ac53cd32455be685e7463a00 Mon Sep 17 00:00:00 2001 From: topi0247 Date: Sat, 25 Apr 2026 16:03:09 +0900 Subject: [PATCH 2/2] =?UTF-8?q?test:=20Cookie=E8=AA=8D=E8=A8=BC=E3=81=A8OA?= =?UTF-8?q?uth=E3=82=B3=E3=83=BC=E3=83=AB=E3=83=90=E3=83=83=E3=82=AF?= =?UTF-8?q?=E3=81=AE=E3=83=86=E3=82=B9=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Cookie経由での認証テストを追加(このテストがあれば本番エラーは事前に検出できた) - OAuthコールバックのリクエストスペックを新規追加 - rails_same_site_cookieをGemfileから削除(Rack3.xでArray Set-Cookieヘッダーのstripエラーが発生するため) - Rails 7.1のcookies_same_site_protection = :noneで代替済み - OmniauthCallbacksControllerにset_flash_messageのno-opオーバーライドを追加(APIモードでflash未使用のため) Co-Authored-By: Claude Sonnet 4.6 --- back/Gemfile | 2 - back/Gemfile.lock | 5 -- .../auth/omniauth_callbacks_controller.rb | 4 ++ back/spec/requests/api/v1/users_spec.rb | 13 ++++ .../requests/auth/omniauth_callbacks_spec.rb | 62 +++++++++++++++++++ 5 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 back/spec/requests/auth/omniauth_callbacks_spec.rb diff --git a/back/Gemfile b/back/Gemfile index b2a120a..fdab0f8 100644 --- a/back/Gemfile +++ b/back/Gemfile @@ -64,7 +64,5 @@ gem 'omniauth-github' gem "omniauth-rails_csrf_protection" # GitHubAPI用 gem "octokit" -# フロントとバックを分けているので同じサイト判定させるためのgem -gem 'rails_same_site_cookie' # envを使うためのGem gem 'dotenv-rails' \ No newline at end of file diff --git a/back/Gemfile.lock b/back/Gemfile.lock index ce32ff8..f5c2438 100644 --- a/back/Gemfile.lock +++ b/back/Gemfile.lock @@ -241,9 +241,6 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - rails_same_site_cookie (0.1.9) - rack (>= 1.5) - user_agent_parser (~> 2.6) railties (7.1.3.2) actionpack (= 7.1.3.2) activesupport (= 7.1.3.2) @@ -292,7 +289,6 @@ GEM tzinfo (2.0.6) concurrent-ruby (~> 1.0) uri (0.13.0) - user_agent_parser (2.17.0) version_gem (1.1.4) warden (1.2.9) rack (>= 2.0.9) @@ -326,7 +322,6 @@ DEPENDENCIES puma (>= 5.0) rack-cors rails (~> 7.1.3, >= 7.1.3.2) - rails_same_site_cookie rspec-rails shoulda-matchers tzinfo-data diff --git a/back/app/controllers/auth/omniauth_callbacks_controller.rb b/back/app/controllers/auth/omniauth_callbacks_controller.rb index c017adf..3bb0bd4 100644 --- a/back/app/controllers/auth/omniauth_callbacks_controller.rb +++ b/back/app/controllers/auth/omniauth_callbacks_controller.rb @@ -1,6 +1,10 @@ class Auth::OmniauthCallbacksController < DeviseTokenAuth::OmniauthCallbacksController skip_before_action :set_auth_headers_from_cookies + # API-only mode does not include flash, so no-op to prevent NameError + def set_flash_message(key, kind, options = {}); end + alias_method :set_flash_message!, :set_flash_message + def redirect_callbacks user = User.from_omniauth(request.env['omniauth.auth']) diff --git a/back/spec/requests/api/v1/users_spec.rb b/back/spec/requests/api/v1/users_spec.rb index be25a1a..159a61f 100644 --- a/back/spec/requests/api/v1/users_spec.rb +++ b/back/spec/requests/api/v1/users_spec.rb @@ -12,6 +12,19 @@ expect(json['success']).to be true expect(json['user']['name']).to eq(user.name) end + + it 'Cookieで認証できる' do + tokens = auth_headers(user) + cookies['access-token'] = tokens['access-token'] + cookies['client'] = tokens['client'] + cookies['uid'] = tokens['uid'] + cookies['expiry'] = tokens['expiry'] + + get '/api/v1/me' + expect(response).to have_http_status(:ok) + json = JSON.parse(response.body) + expect(json['success']).to be true + end end context '未認証の場合' do diff --git a/back/spec/requests/auth/omniauth_callbacks_spec.rb b/back/spec/requests/auth/omniauth_callbacks_spec.rb new file mode 100644 index 0000000..d83a4bb --- /dev/null +++ b/back/spec/requests/auth/omniauth_callbacks_spec.rb @@ -0,0 +1,62 @@ +require 'rails_helper' + +RSpec.describe 'Auth::OmniauthCallbacks', type: :request do + let(:omniauth_auth) do + OmniAuth::AuthHash.new({ + provider: 'github', + uid: 'github_uid_test', + info: { name: 'Test User', email: 'test@example.com', nickname: 'testuser' }, + credentials: { token: 'github_access_token' } + }) + end + + before do + OmniAuth.config.test_mode = true + OmniAuth.config.request_validation_phase = nil + OmniAuth.config.mock_auth[:github] = omniauth_auth + end + + after do + OmniAuth.config.test_mode = false + OmniAuth.config.request_validation_phase = OmniAuth::AuthenticityTokenProtection + end + + describe 'GET /omniauth/github/callback' do + context '新規ユーザーの場合' do + it 'ユーザーを作成してrecordページにリダイレクトする' do + get '/omniauth/github/callback' + expect(response).to redirect_to("#{ENV['FRONT_URL']}/record") + end + + it '認証Cookieをセットする' do + get '/omniauth/github/callback' + expect(response.cookies['access-token']).to be_present + expect(response.cookies['client']).to be_present + expect(response.cookies['uid']).to be_present + expect(response.cookies['expiry']).to be_present + end + end + + context '既存ユーザーの場合' do + before { create(:user, uid: 'github_uid_test', provider: 'github') } + + it 'recordページにリダイレクトする' do + get '/omniauth/github/callback' + expect(response).to redirect_to("#{ENV['FRONT_URL']}/record") + end + end + + context 'GitHubユーザーが取得できない場合' do + before do + allow(User).to receive(:from_omniauth).and_return( + build(:user, uid: nil).tap { |u| u.valid? } + ) + end + + it 'エラーページにリダイレクトする' do + get '/omniauth/github/callback' + expect(response.location).to include('status=error') + end + end + end +end