1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Next.js13】axiosでwithCredentialsを入れたのにcookieが送信されない話

Posted at

はじめに

 cookieにセットされたトークンを用いるため、axiosのオプションにwithCredentialsを追加しましたが、APIを叩いても401エラーとなり弾かれてました。自分の理解の浅さ故、何日も溶かしてしまったので、初学者の備忘録として残します。

結論

 Next.jsでは、Server Componentsの使用をデフォルトとしているため、クライアント側にセットされたcookieをサーバーサイドで読み取ることができません。なので、一度cookieから吸い上げて、headerオプションにセットする必要がありました。

export async function getServerSideProps(context) {
	const apidata = await getApi(context.req.cookies);
	return { props: { api: apidata } };
}


import axios from 'axios';

export default async function getApi(cookies) {
	const access_token = cookies['access_token'];

	return await axios
		.get('http://nginx-back:80/api', {
			headers: {
				'Content-Type': 'application/json;',
                // withCredentials: true,  ←これではダメ
				Authorization: `JWT ${access_token}`,
			},
		})
		.then((res) => {
			const data = res.data as Data[];
			return data;
		})
		.catch((e) => console.log(`エラーが発生しました: ${e}`));
}

Server Components、Client Componentsとは何か?

 その名の通りですが、Server Componentsは、サーバー側でレンダリングされるコンポーネント。Client Componentsは、クライアント側でレンダリングされるコンポーネントです。

 サーバーサイド・クライアントサイドにレンダリングを分けることによって、「従来のサーバーレンダリングのパフォーマンス向上」と「クライアントサイドのリッチな双方向性」を両立させながら、サーバー・クライアント両方の環境でアプリケーションを構築できるようになりました。

 appディレクトリ内のコンポーネントは、デフォルトでServer Componentsとなり、Client Componentsとして扱うためには、コードの先頭(import文よりも上)に'use client'とつける必要があります。

'use client'

import { useState } from 'react'

export default function Counter() {
 const [count, setCount] = useState(0)

 return (
   <div>
     <p>You clicked {count} times</p>
     <button onClick={() => setCount(count + 1)}>Click me</button>
   </div>
 )
}

Sever Componentsのメリット

 以下、公式からの引用です。
 

  • データ取得
     データの取得をデータソースに近いサーバーに移すことができます。これにより、レンダリングに必要なデータを取得する時間が短縮され、クライアントが行うべきリクエストの回数が減るため、パフォーマンスが向上します。
     
  • セキュリティ
     トークンやAPIキーなどの機密データやロジックを、クライアントに公開するリスクなしにサーバー上に保持できます。
     
  • キャッシュ
     サーバー上でレンダリングすることで、結果をキャッシュし、後続のリクエストやユーザー間で再利用することができます。これにより、各リクエストで実行されるレンダリングとデータ取得の量を減らすことで、パフォーマンスを向上させ、コストを削減することができます。
     
  • バンドルサイズ
     以前はクライアントJavaScriptのバンドルサイズに影響を及ぼしていた大きな依存関係をサーバーに残すことができます。クライアントがServer Componentの JavaScript をダウンロード、解析、実行する必要がないため、インターネットの速度が遅いユーザーや性能の低いデバイスを使用しているユーザーにとって有益です。
     
  • 初期ページロードとファースト・コンテントフル・ペイント(FCP)
     サーバー上で、ページのレンダリングに必要なJavaScriptをクライアントがダウンロード、解析、実行するのを待たずに、ユーザーがすぐにページを表示できるようにHTMLを生成することができます。
     
  • 検索エンジン最適化とソーシャルネットワークの共有性
     レンダリングされたHTMLは、検索エンジンのボットがページをインデックスしたり、ソーシャルネットワークのボットがページのソーシャルカードプレビューを生成するために使用することができます。
     
  • ストリーミング
     レンダリング作業を分割して、準備ができ次第クライアントにストリーミングできます。これにより、ユーザーはページ全体がサーバーでレンダリングされるのを待つことなく、ページの一部を早めに見ることができます。

おわりに

 公式リファレンスをちゃんと読むって大事ですね。参照する癖をつけておけば、何日もネットを彷徨うこともなかったと思います。

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?