現在、ポートフォリオ を作成中です。
ReactとRails(apiモード)で通信をさせているのですが、かれこれ2−3日詰まってます
やりたいこと
ReactとRailsでCookieを利用した通信をしたい
クライアント側(React側)からcookieを送信して、railsのsessionにユーザー情報を格納したい
試したこと
Corsの設定やsession_storeなどのRailsの設定はいろんな記事を参考にして設定済
loginメソッドで通信時にはレスポンスcookieが帰ってきていることを確認できるのですが、
その後の認証ではリクエストCookieが送れておらず?Rails側で認証できていません。
初回のloginの際には、正しい挙動でCookieも帰ってきている(レスポンスCookie)(session情報も返すようにしている)
しかし、マイページ遷移後のlogged_in(apiに認証しているかたたきにいくgetメソッド)ではcookieの表記が見当たらず、
railsでsession配列にはいらずcurrent_userがnil状態になります。(リクエストCookieがない)
該当ソースコード
useCheckAuth.js
1 2// importなど省略 3// useEffectでapiを叩きに行くhooksです 4 5const CheckAuth = useCallback(async () => { 6 await axios 7 .get(LoggedinUrl, { withCredentials: true }) 8 .then((response) => { 9 if (response.data.status === 200) { 10 setLoginUser(response.data); 11 setLoginState(true); 12 } 13 // 認証できなかった時のエラー 14 else if (response.data.status === 401) { 15 setLoginUser(null); 16 setLoginState(false); 17 showMessage({ title: `${response.data.errors}`, status: 'error' }); 18 history.push('/login'); 19 } 20 // うまくgetできなかった時のエラー 21 }) 22 .catch(() => { 23 showMessage({ title: '認証が確認できません、再度ログインし直してください', status: 'error' }); 24 setLoginUser(null); 25 setLoginState(false); 26 history.push('/login'); 27 });
↓railsでcreateメソッドはログインするためのメソッド、logged_in?はログイン状態を確認するメソッド
sessons_controller/rb
1# 2module Api 3 module V1 4 class SessionsController < ApplicationController 5 before_action :current_user, only: [:logged_in?] 6 7 def create 8 user = User.find_by(email: session_params[:email]) 9 10 if user && user.authenticate(session_params[:password]) 11 session[:user_id] = user.id 12 render json: { 13 status:200, 14 logged_in: true, 15 user: user, 16 session: session { user_id }, 17 }, methods: [:avatar_url] 18 else 19 render json: { status: 401, errors: ["正しいメールアドレス・パスワードを入力して下さい"], user: user} 20 end 21 end 22 23 def logged_in? 24 #おろらく@current_userがnilになっているため、帰ってこない 25 @current_user ||= User.find_by(id: session[:user_id]) if session[:user_id] 26 if @current_user 27 render json: { 28 status: 200, 29 logged_in: true, 30 user: current_user, 31 }, methods: [:avatar_url] 32 else 33 render json: { 34 status:401, 35 logged_in: false, 36 # errors: @current_user.errors.full_messages 37 session: session[:user_id], 38 user: @current_user, 39 errors: ["ログインしてください"] 40 } 41 end 42 end 43 private 44 45 def session_params 46 params.require(:user).permit(:email, :password) 47 end 48 end 49 end 50end
application_controller.rb
1class ApplicationController < ActionController::API 2 include ActionController::Helpers 3 skip_before_action :verify_authenticity_token, raise: false 4 # Railsが認証トークンを使用しないように 5 helper_method :login, :current_user 6 7 # セッションに引数のuserのidを格納する 8 def login(user) 9 session[:user_id] = user.id 10 end 11 12 def current_user 13 if session[:user_id] 14 @current_user ||= User.find(session[:user_id]) 15 end 16 end 17end
sessions_store.rb
1 2if Rails.env == 'environment' 3 Rails.application.config.session_store :cookie_store,key:'_cooklog_session', 4 # same_site::none, 5 secure: false, 6 domain:'localhost:3001' 7else 8 Rails.application.config.session_store :cookie_store,key:'_cooklog' 9end
その他
cookieのsecure属性やhttponlyのオプションなどが関係しているのでしょうか?
参考記事
追記
コンソールには下記のようなエラーが出ていますが、これはuserというステートに上記で入れる予定のuser情報がnull
のため、出ているエラーです。
ステートの値がnullなので、レンダリングするビューの値がおかしくなり、画面が真っ白になります
質問が解消されれば共連れで解消するはずです。
Mypage.jsx:92 Uncaught TypeError: Cannot read properties of null (reading 'user') at Mypage.jsx:92:1 at renderWithHooks (react-dom.development.js:14985:1) at updateFunctionComponent (react-dom.development.js:17356:1) at updateSimpleMemoComponent (react-dom.development.js:17215:1) at beginWork (react-dom.development.js:19140:1) at HTMLUnknownElement.callCallback (react-dom.development.js:3945:1) at Object.invokeGuardedCallbackDev (react-dom.development.js:3994:1) at invokeGuardedCallback (react-dom.development.js:4056:1) at beginWork$1 (react-dom.development.js:23964:1) at performUnitOfWork (react-dom.development.js:22776:1) at workLoopSync (react-dom.development.js:22707:1) at renderRootSync (react-dom.development.js:22670:1) at performSyncWorkOnRoot (react-dom.development.js:22293:1) at react-dom.development.js:11327:1 at unstable_runWithPriority (scheduler.development.js:468:1) at runWithPriority$1 (react-dom.development.js:11276:1) at flushSyncCallbackQueueImpl (react-dom.development.js:11322:1) at flushSyncCallbackQueue (react-dom.development.js:11309:1) at scheduleUpdateOnFiber (react-dom.development.js:21893:1) at dispatchAction (react-dom.development.js:16139:1) at useAuthCheck.js:30:1 at async useAuthCheck.js:21:1
追記
ログイン後 画面が白くなり、コンソールにエラーがでます。
ただ、推測ですが画面の
useEffectのcheckAuthをコメントアウトした場合
このように意図した表示になります
(いま出ているエラーは別のエラーだと考えています)
追記
同様にrailsの他のcurrent_userを使うメソッドでエラーが出ています。
(原因は同じだと思われます)
追記
loginメソッド(初回ログイン)時のリクエストヘッダー
リクエスト URL: http://localhost:3000/api/v1/login リクエスト メソッド: POST ステータス コード: 200 OK リモート アドレス: [::1]:3000 参照ポリシー: strict-origin-when-cross-origin Access-Control-Allow-Credentials: true Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD Access-Control-Allow-Origin: http://localhost:3001 Access-Control-Expose-Headers Access-Control-Max-Age: 7200 Cache-Control: max-age=0, private, must-revalidate Content-Type: application/json; charset=utf-8 ETag: W/"a2d15844da7ee30a59563aa8ba15c96b" Referrer-Policy: strict-origin-when-cross-origin Set-Cookie: _session_id=3sELA%2Ft%2BfW%2FtPZp30qki34bqKxl9O2YMpndIajOsR7ldUYouceOFC4srRNK%2BMo3Hs89zMnBsATw%2B3bDKV1W1dZL9BEbDNOkgPTQowMAAZ0ekRTzjuTHATJMasqSaInXoX50xULu%2BONMO%2FEYecfgpoGvDYKu9EgxX1RnO6Sj6t4R6%2BTg92%2BYH5eojmKTvRQqtJPcjW4a3XFess70RxzBLPho2giFIBIM%3D--j4R2F%2BRxIz0kVE6v--G%2FbF78BFI9eF8yT1E3yvcQ%3D%3D; path=/; HttpOnly; SameSite=None Transfer-Encoding: chunked Vary: Origin X-Content-Type-Options: nosniff X-Download-Options: noopen X-Frame-Options: SAMEORIGIN X-Permitted-Cross-Domain-Policies: none X-Request-Id: 5c7c3820-d14c-42e6-960f-97f9801cc508 X-Runtime: 0.435988 X-XSS-Protection: 1; mode=block Accept: application/json, text/plain, */* Accept-Encoding: gzip, deflate, br Accept-Language: ja,en-US;q=0.9,en;q=0.8 Connection: keep-alive Content-Length: 59 Content-Type: application/json Host: localhost:3000 Origin: http://localhost:3001 Referer: http://localhost:3001/ sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="101", "Google Chrome";v="101" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "macOS" Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-site User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36
logged_inメソッド(認証確認)のリクエストヘッダー
リクエスト URL: http://localhost:3000/api/v1/logged_in リクエスト メソッド: GET ステータス コード: 200 OK リモート アドレス: [::1]:3000 参照ポリシー: strict-origin-when-cross-origin Access-Control-Allow-Credentials: true Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD Access-Control-Allow-Origin: http://localhost:3001 Access-Control-Expose-Headers Access-Control-Max-Age: 7200 Cache-Control: max-age=0, private, must-revalidate Content-Type: application/json; charset=utf-8 ETag: W/"3c03e572d8a333aa7c5f90cfc90172d5" Referrer-Policy: strict-origin-when-cross-origin Vary: Origin X-Content-Type-Options: nosniff X-Download-Options: noopen X-Frame-Options: SAMEORIGIN X-Permitted-Cross-Domain-Policies: none X-Request-Id: 2bb9d371-3fa9-4555-8f03-68e0359772e9 X-Runtime: 0.330237 X-XSS-Protection: 1; mode=block Accept: application/json, text/plain, */* Accept-Encoding: gzip, deflate, br Accept-Language: ja,en-US;q=0.9,en;q=0.8 Connection: keep-alive Host: localhost:3000 If-None-Match: W/"3c03e572d8a333aa7c5f90cfc90172d5" Origin: http://localhost:3001 Referer: http://localhost:3001/ sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="101", "Google Chrome";v="101" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "macOS" Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-site User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36

回答1件
あなたの回答
tips
プレビュー