質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Cookie

HTTPにおけるCookieとは、クライアントのウェブブラウザ上に保存された一時的なデータを指します。クライアント側のJavaScriptでも、サーバー側のHTTPヘッダーでもクッキーの読み書き・修正・削除が可能です。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

2648閲覧

ReactとRails-apiでCookieを利用した通信を行いたい

kiyomasa

総合スコア40

Cookie

HTTPにおけるCookieとは、クライアントのウェブブラウザ上に保存された一時的なデータを指します。クライアント側のJavaScriptでも、サーバー側のHTTPヘッダーでもクッキーの読み書き・修正・削除が可能です。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

1クリップ

投稿2022/06/05 05:53

編集2022/06/05 22:19

現在、ポートフォリオ を作成中です。
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のオプションなどが関係しているのでしょうか?

参考記事

https://qiita.com/kurawo___D/items/d5257e69bcb300908687#1appjs%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%AB%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%81%AE%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E7%8A%B6%E6%85%8B%E3%81%8C%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%81%A7%E3%81%8D%E3%82%8B%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B5%E3%82%A4%E3%82%AF%E3%83%AB%E3%82%92%E5%AE%9A%E7%BE%A9%E3%81%99%E3%82%8B

追記

コンソールには下記のようなエラーが出ていますが、これは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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ockeghem

2022/06/05 06:45

開発者ツールのコンソール(Console)でエラー等が表示されていませんか? 表示されていたら質問に追記してください。
kiyomasa

2022/06/05 06:53

ご確認いただきありがとうございます。追記しました。他必要なことがあればお知らせください。
ockeghem

2022/06/05 08:32

追記ありがとうございます。ブラウザ(Google Chrome等)の開発者ツールの「コンソール」または「Console」にはエラーは表示されていませんか?
kiyomasa

2022/06/05 09:40

一旦、すべて追記しました。よろしくお願いします。。。
ockeghem

2022/06/05 11:45

すみません、明確に書いてなかったですが、ログイン処理ではブラウザの開発者ツールのコンソールにはエラーは表示されていませんか?
kiyomasa

2022/06/05 13:16

すみません、ログイン処理では、コンソール上にエラーは見つかりませんでした。 一応追記はしましたが、current_userがnilのせいで別の所がエラーになっており、それが表示されている形です。
ockeghem

2022/06/05 14:46

ブラウザの開発者ツールで、login処理のネットワークタブにて「ヘッダー」の箇所を見せてください。Cookieがセットされていない原因を知るには、ヘッダを見る必要があります。
kiyomasa

2022/06/05 22:20

追記いたしました。他必要なものあればお知らせください。
guest

回答1

0

ベストアンサー

コメントでのやりとりありがとうございます。原因がわかりました。
添付いただいた2枚目の画像のCookieのSameSite欄の「None」の前にⓘという記号がついています。ここにマウスカーソルをあててしばらくすると、以下のようなエラーメッセージが表示されるはずです(日本語訳されているかもしれません)。

Cookie詳細

この意味は、SameSite=NoneになっているがSecure属性がないということで、Google ChromeではCookieにSameSite=Noneが指定されている場合は、Secure属性もついていないと、Cookieが受理されないのです。
では、Secure属性をつければよいかというと、そうではありません。Secure属性をつけたばあいは、HTTPSでないとCookieが送信されなくなります。
なので、正解は、「SameSite属性を何も指定しない」ですが、Google Chromeの場合SameSite属性を指定しない場合SameSite=Laxと解釈されるため、SameSite属性の指定を「しない」方法がよくわからない場合は、SameSite=Laxを指定する案も考えられます。

さしあたりすぐに動かしたい場合は、Google Chromeではなく、Firefoxを使えば、現在のところ上記のような制限はないため、この箇所については問題なくなると予想します。

投稿2022/06/06 00:04

ockeghem

総合スコア11701

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kiyomasa

2022/06/06 12:38

わかりやすい回答をありがとうございます。 クロームの問題だったんですね、SameSite=LAXにするとPost通信や画像のやり取りができなくなるらしいので、ひとまずFireFoxをDLしてやってみたところ、 Samesite属性ないよと警告は出るものの、問題なく動きました。 お忙しいところご助力いただき、本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問