フロントエンドなみなさんこんにちは。2019年3月より、業務委託という形式で株式会社Photocreateの運営するスクールフォト販売サイト「スナップスナップ」のリニューアルプロジェクトをお手伝いさせていただきました。今回はその中でチームの仲間とチャレンジした課題についてご紹介したいと思います。はじめに昨今のフロントエンド界隈はエッジノードでのpre-renderingエコシステムが非常に充実してきました。Application開発に求められることも減ってきた気がします。いえ依然としてSSR機構を求められる案件も少なくなく、無垢な初心者が誤って迷い込もうものならその複雑怪奇な世界の闇にたちまち飲み込まれてしまうことでしょう。本記事では認証認可とは切っても切り離せない「Cookie」という切り口でその一端をご紹介したいと思います。前提となるアーキテクチャ一般的なログイン※以下の内容は実在のWebサービスの構成に若干のフェイクを加えたものです。Token)を払い出し、フロントエンドはAPIのリクエストヘッダーにTokenを含めることで認証を突破フロントエンドでのToken永続化にはCookieを利用よくあるWebアプリケーションの構成ですね。Token>が含まれおり、ログインに成功した段階で自動的にブラウザにCookieが保存されます。オプションも設定されており、JavaScriptからCookieのread/writeを行えないようにしています。expireの概念があり、その有効性には期限を設けています。ところがこのRefreshの仕組みがちょっとやっかいで、今回のケースでもかなりのネックになりました。APIを実行という要件になっています。Tokenの二元管理は行なっていません。クライアントでページ遷移を行う際のシーケンス図はこんな感じ👇Tokenの更新をかなりアグレッシブに行う設計になっています。APIを実行という要件が今回の肝になる部分です。APIを触る事はありません。Storageに値をドメイン情報と合わせて保管してくれます。Headerに付与されてリクエスト先に渡されるというのが基本的な仕組みです。Domainオプションを利用してサブドメインまでを含める事が可能です。DomainオプションによってAPIサーバーに対しても、SSRサーバーに対してもCookieが渡されるようになっています。詳細にCookieの仕様を学びたい方はMDNのドキュメントを読む事をお勧めします。https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Set-CookieSSRサーバーを経由することによるCookieの消失ここからは実際に以下のようなケースにおける問題点と解決策をそれぞれ紹介していきたいと思います。Backend本題に立ち戻りますが、本アプリケーションは(初回アクセス時のみ)クライアントとAPIサーバーの中間にSSRサーバーが挟まれるため、何もしないままだとクライアントの持つCookieがAPIサーバーまで到達しなくなってしまいます。サーバーを跨ぐので当然ですね。ctx.req内のリクエスト情報にアクセスできます。ContextにはClientがSSRサーバーにアクセスした際の情報がCookieに限らずいろいろと含まれているため、無難に丸ごとforwardしてあげるのが良いでしょう。Server(共通ドメイン)に向けることのみを前提としているため、きちんとブラウザの挙動を再現する場合はドメインの検証ロジックをいれてあげてください。Headerのforwardingについて考えてみます。オブジェクトを加工することでBackendからSSRサーバーに渡されたCookieをClientに伝播させる事が可能です。set-cookieヘッダーのみをforwardしたい」というものが発生したため、最終的には以下のような実装になりました。Client内で通信に用いているライブラリはaxiosです。HeaderにCookie情報が付与されるはず!BFF内のリクエストスコープにおけるCookie共有ここまでが初級編、ここからグッと複雑度があがります。一般的にSPAで画面を描画する際は1つのHTMLために複数回のAPIコールが発生するものです。Eで利用しなくてはならないケースを考えてみましょう。Storageへread/writeが走ります。Headerに含める事が可能になります。Renderingリクエストスコープ内で使い回しが効くような仕組みを考えてみましょう。etc...諸々の属性を保持できるものの、結局のところCookieの受け取り手が知りたいのはKey名と対応する値のMapであると言う事ができます。Storageを「$ssrCookie」という名前でNuxtのContextに注入してあげましょう。string>}続いて初期化のためのPluginを記述。Storageの準備が完了です。Storageに格納する処理を記述します。$ssrCookieに格納しています。libraryも探せばあるかもしれません。PropertyのSymbolize等は行なっていないので、時系列で見たときにより新しいResponseの値で上書きするようになっている点に注意です。Headerをforwardしているというような解説を先立って行いました。$ssrCookieに格納した内容での上書きも下記のように同じ部分で行います。Headerにembedしています。どこまで作り込むかは要件次第で調整してあげてください。interceptorを作り込むのが筋かなと思います。API)etc...が他にも積まれています😇まとめCookieという割と大事な部分のダーティーな処理をブラウザが引き受けてくれてることにあらためて感謝。OnlyなSPA開発におけるブラウザの「当たり前」をNode.js上で再現するだけでもかなりの労力だなと思いました。合わせてセキュリティ要件も担保しなくてはいけないので、許容できる複雑度のバランスを取るのに苦労しました。今回の発端は特殊な認証・認可の仕組みにありましたが、通常のケースでもCookieの管理はいずれぶつかる問題なのでその勉強になって良かったです。本記事でお届けできたのはSSRのつらみの2%程度でしかないので、今後も機会があればネタを提供したいなと思います。