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

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

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

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

AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Q&A

解決済

2回答

11703閲覧

Set-Cookieは返ってきているがCookieがブラウザに保存されない

fresh_fish

総合スコア20

Cookie

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

AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

0グッド

2クリップ

投稿2021/11/15 15:26

編集2021/11/16 03:13

発生している問題・エラーメッセージ

Next.js(Vercel) Express(APIGateway, LambdaをServerlessFrameworkで管理)
上記の構成でWebアプリケーションを開発しています。
認証でCookieを使用するのですが本番環境だとCookieがブラウザに保存されず困っております。

APIGateway周辺が問題なのかと思いましたが応答ヘッダーにはちゃんとSet-Cookie属性が付いているのでどこが原因なのかわからないです。
ブラウザはFireFoxとChromeで試しましたがどちらもダメでした。
エラー文も警告文も出ず途方に暮れているので何か原因らしきものがわかれば教えていただけると助かります。

####開発環境でのCookie
開発環境

####本番環境でのCookie(保存されていない)
本番環境

####ブラウザのdeveloperConsole出力

POST Schema: https Host: https://acyt1ofpm9.execute-api.ap-northeast-1.amazonaws.com/dev/api/v1/auth/login Filename: /dev/api/v1/auth/login ステータス 200 OK バージョンHTTP/2 転送量1.32 KB (382 バイト サイズ) リファラーポリシーstrict-origin-when-cross-origin
応答ヘッダー access-control-allow-credentials: true access-control-allow-origin: https://mizuho-engineering-timecard-system.vercel.app content-length: 386 content-type: application/json; charset=utf-8 date: Mon, 15 Nov 2021 14:04:46 GMT etag: W/"182-3X2mEAg0rF0aNx3B2MUnxo2WQww" set-cookie: refreshToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoi566h55CG6ICFIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNjM2OTg3NDg4LCJleHAiOjE2NDQ3NjM0ODh9.XcanhEVZDHsLWw-tKSRAUZmQvGFuH1cbSGGUqrRmpN8; Path=/; Secure; SameSite=None vary: Origin via: 1.1 64deaa7770e2273b39002266d56d8170.cloudfront.net (CloudFront) x-amz-apigw-id: I2VXuF8wNjMFUeg= x-amz-cf-id: -nIggNVibO-aX4w-wuGL0x0iSmwnjLgOi4IYDNCKugADqC6IhFV-0A== x-amz-cf-pop: NRT12-C4 x-amzn-remapped-content-length: 386 x-amzn-requestid: 0c574b80-c141-4d29-973c-a2e7a8f6bfc6 x-amzn-trace-id: Root=1-619268fe-656b7847664c394d3e7f157f;Sampled=0 x-cache: Miss from cloudfront x-powered-by: Express
要求ヘッダー Accept application/json, text/plain, */* Accept-Encoding gzip, deflate, br Accept-Language ja,en-US;q=0.7,en;q=0.3 Authorization Bearer Connection keep-alive Content-Length 43 Content-Type application/json Cookie refreshToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoi566h55CG6ICFIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNjM2OTg3NDE1LCJleHAiOjE2NDQ3NjM0MTV9.FRln36Pl6XbkUWuE4aMsFimskyWAwbdo4yNd0XqBQZA Host acyt1ofpm9.execute-api.ap-northeast-1.amazonaws.com Origin https://mizuho-engineering-timecard-system.vercel.app Referer https://mizuho-engineering-timecard-system.vercel.app/ Sec-Fetch-Dest empty Sec-Fetch-Mode cors Sec-Fetch-Site cross-site TE trailers User-Agent Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763
応答Cookie refreshToken: path: "/" samesite: "None" secure: true value: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoi566h55CG6ICFIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNjM2OTg3NDg4LCJleHAiOjE2NDQ3NjM0ODh9.XcanhEVZDHsLWw-tKSRAUZmQvGFuH1cbSGGUqrRmpN8 要求Cookie refreshToken: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoi566h55CG6ICFIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNjM2OTg3NDE1LCJleHAiOjE2NDQ3NjM0MTV9.FRln36Pl6XbkUWuE4aMsFimskyWAwbdo4yNd0XqBQZA

応答Cookieと要求CookieでrefreshTokenの値が違うのは関係ないでしょうか?

プログラム側(Express)のコード

.......... if (process.env.NODE_ENV === "production") { //本番環境ではsameSite: "none"とsecure: trueを設定しないとコンソールで警告が出る res.cookie("refreshToken", refreshToken, { sameSite: "none", secure: true }); } else { res.cookie("refreshToken", refreshToken); } ..........

関係ないかもしれませんが一応ServerlessFrameworkの構成ファイルも載せておきます

serverlessyml

1service: mizuho-timecard 2 3provider: 4 name: aws 5 runtime: nodejs12.x 6 region: ap-northeast-1 7 iamRoleStatements: 8 - Effect: Allow 9 Action: 10 - dynamodb:Query 11 - dynamodb:Scan 12 - dynamodb:GetItem 13 - dynamodb:PutItem 14 - dynamodb:UpdateItem 15 - dynamodb:DeleteItem 16 Resource: 17 - arn:aws:dynamodb:${self:provider.region}:*:table/Timecards 18 - arn:aws:dynamodb:${self:provider.region}:*:table/Timecards/index/* 19 20package: 21 exclude: 22 - script/** 23 - .git/** 24 - test/** 25 - src/** 26 - README.md 27 - .env 28 29functions: 30 timeCard: 31 handler: dist/lambda.handler 32 events: 33 - http: ANY / 34 - http: 'ANY {proxy+}' 35 36resources: 37 Resources: 38 timecards: 39 Type: AWS::DynamoDB::Table 40 Properties: 41 TableName: Timecards 42 AttributeDefinitions: 43 - AttributeName: user 44 AttributeType: S 45 - AttributeName: attendance 46 AttributeType: S 47 KeySchema: 48 - AttributeName: user 49 KeyType: HASH 50 - AttributeName: attendance 51 KeyType: RANGE 52 GlobalSecondaryIndexes: 53 - IndexName: usersIndex 54 KeySchema: 55 - AttributeName: attendance 56 KeyType: HASH 57 Projection: 58 ProjectionType: ALL 59 ProvisionedThroughput: 60 ReadCapacityUnits: 1 61 WriteCapacityUnits: 1 62 ProvisionedThroughput: 63 ReadCapacityUnits: 1 64 WriteCapacityUnits: 1 65 TimeToLiveSpecification: 66 AttributeName: "expirationTime" 67 Enabled: true

補足情報(FW/ツールのバージョンなど)

npm list --depth 0 mizuho-timecard@1.0.0 /home/kanta/workspace/mizuho-timecard/mizuho-timecard-backend ├── @fortawesome/free-solid-svg-icons@5.15.4 ├── @fortawesome/react-fontawesome@0.1.16 ├── @line/bot-sdk@7.4.0 ├── @types/bcrypt@5.0.0 ├── @types/cors@2.8.12 ├── @types/csurf@1.11.2 ├── @types/express-session@1.17.4 ├── @types/express@4.17.13 ├── @types/jest@27.0.2 ├── @types/jsonwebtoken@8.5.5 ├── @types/node-geocoder@3.24.2 ├── @types/node@16.10.3 ├── @types/sinon-express-mock@1.3.9 ├── @types/supertest@2.0.11 ├── @types/xlsx-populate@1.19.1 (git+ssh://git@github.com/JanLoebel/types-xlsx-populate.git#7ef81174e495fe9ef2689bd329499f81a2a93d43) ├── @typescript-eslint/eslint-plugin@5.3.1 ├── @typescript-eslint/parser@5.3.1 ├── @vendia/serverless-express@4.3.11 ├── aws-sdk@2.995.0 ├── bcrypt@5.0.1 ├── body-parser@1.19.0 ├── cors@2.8.5 ├── csurf@1.11.0 ├── dayjs@1.10.7 ├── eslint-config-prettier@8.3.0 ├── eslint@8.2.0 ├── express-validator@6.12.2 ├── express@4.17.1 ├── faker@5.5.3 ├── geo-position.ts@1.4.1 ├── jest@27.2.5 ├── jsonwebtoken@8.5.1 ├── node-geocoder@3.27.0 ├── nodemon@2.0.13 ├── npm-run-all@4.1.5 ├── prettier@2.4.1 ├── rimraf@3.0.2 ├── sinon-express-mock@2.2.1 ├── sinon@11.1.2 ├── supertest@6.1.6 ├── ts-jest@27.0.5 ├── ts-node-dev@1.1.8 ├── ts-node@10.2.1 ├── typescript@4.4.4 └── xlsx-populate@1.21.0
sls --version Framework Core: 2.60.0 (standalone) Plugin: 5.4.4 SDK: 4.3.0 Components: 3.17.1

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

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

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

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

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

tanat

2021/11/16 01:24

Cookieの確認はどのようにされていますか?
fresh_fish

2021/11/16 02:27

developerToolで確認しています スクリーンショットを載せましたのでご確認ください
miyabi-sun

2021/11/16 05:41

> Next.js(Vercel) Express(APIGateway, LambdaをServerlessFrameworkで管理) ん?って事はHTML・JSファイルはVercelから受け取って、 ユーザーデータはLambdaとかのAWSで管理してるってことよね? 要するに1個のサービスを2個のホスト・ドメインで管理してるってことよね。 Cookieはホスト・ドメイン毎の管理になるから そこを無視したCookie情報の授受は出来ないけど、ちゃんとハンドリング出来てる? 質問文を見る限り、このホスト毎制約が意識から漏れているような気がする。
fresh_fish

2021/11/16 07:31

回答ありがとうございます 私の認識だとオリジン間リクエストの許可(sameSite: "none")がそこに当たると思っていたのですが違いますでしょうか。 先ほどドメインを取得して同ドメイン(example.com, api.example.com)とDNS設定してきましたので反映されたらまた報告します。
miyabi-sun

2021/11/16 08:46

SameSiteの設定は初耳でしたが、Noneにすることで「従来の挙動」という事ですので、 やはりサードパーティーCookieはサードパーティーCookieのままなのでは? というわけで、多分「違う話だよ」が正解になるんだと思います。 入場が「vercel.app」でクロスドメインの「aws」に向けてAjax通信(?)を飛ばしているわけなので awsが「このキー名に対してCookie作ってよ」といったら ブラウザ「awsホストとの通信でCookieを作れと言われたんだからサードパーティーCookie生成するでしょ」という挙動になるんだと思います。 サブドメイン同士ならかなり楽な話になります この記事とかどうでしょうか。 https://qiita.com/il-m-yamagishi/items/9aad5737c80d5bfd5eb8
fresh_fish

2021/11/17 16:41

返信が遅くなり申し訳ございません 設定や情報収集をしていました。 miyabiさんのおっしゃる通りやはり同ドメインにしていなかったことが原因でした。 初歩的なミスでお恥ずかしいのですが助言がなければおそらく気づかなかったです ありがとうございました
fresh_fish

2021/11/17 16:43

ベストアンサーを送りたいのですがコメントには送ることができないみたいなのでもしよければ何か適当に回答を投稿していただけますでしょうか。 手間であれば自己解決として私が投稿いたします
miyabi-sun

2021/11/18 01:32

私はCookieはそこまで詳しくないので確証はなく、 頑張って調査してくださいといった体での依頼という感じでした。 teratailに於ける質問は今後ナレッジとして共有されるべきものなので、 fresh_fishさんが調査した内容を元にSameSiteの効果だとか クロスドメイン、サードパーティーCookieとかのワードを使って良い感じのナレッジを作ってみてください。
fresh_fish

2021/11/18 03:36

調べたことをまとめて回答として投稿します この度はありがとうございました
guest

回答2

0

自己解決

解決方法

フロントエンドのvercelとバックエンドのAPIGatewayでドメインを統一し、Set-Cookieのオプションにdomainを設定する


vercelのドメイン
example.com

APIGatewayのドメイン
api.example.com

Set-Cookie Domain="example.com"

混乱の元

私はクロスドメイン間のCookieのやり取りはSame-Site: "none" を設定することで許可できると思っていました。
しかしSame-Site: "none"はクロスオリジンでのCookie付与を許可するものであり、クロスドメインでのCookieのやり取りを可能にするものではないんです。
クロスオリジンでのCookie付与の許可とは、所謂3rd Party Cookieの取り扱いを許可するということです。広告トラッキングとかの技術ですね。
なのでSame-Site: "none"を設定した場合Cookieがブラウザにセットされていないのではなく、3rdPartyCookieとして保存されているため保存されていてもドメインの違うクライアント側では確認、取り扱いができないということです。

そもそも前提として昔からCookieをクロスドメインで扱う方法はないのですが、Same-Siteオプションがあるせいで勘違いしてしまいました。

ただSame-Siteオプションが最近追加された項目であること、クロスオリジンとクロスドメインの違い、3rdPartyCookieとは何なのか、を理解していないと初学者にはわかりづらいと思います。

この回答が誰かのお役に立てば幸いです。

投稿2021/11/18 04:02

fresh_fish

総合スコア20

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

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

guest

0

自己解決されたとのことですが、根本的に勘違いをされているようなので、念の為。

access-control-allow-origin: https://mizuho-engineering-timecard-system.vercel.app

このヘッダは、APIサーバーが呼び出し側JavaScriptのオリジンを許可するという意味ですが、その文脈では https://mizuho-engineering-timecard-system.vercel.app は呼び出し側JavaScriptのオリジンです。

一方、クッキーがセットされるのはAPIサーバーのホストですが、「本番環境でのCookie(保存されていない)」はAPIサーバーではなく呼び出し側のホストを調べているように見えます。

これは、SameSite=Noneとは無関係の、もっと根本的なところなので、念の為指摘させていただきました。

ホスト名を短く以下のようにして例示しますと、

API: https://api.example.com
呼び出し側: https://www.example.net

このケースですと、クッキーがセットされるのは、api.example.com 側です。そして、APIサーバー側で生成するCORSのヘッダは、

access-control-allow-credentials: true access-control-allow-origin: https://www.example.net

となります。

投稿2021/11/20 09:48

ockeghem

総合スコア11701

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問