nextjs with typescript:29 SSRとCSRとCookie
【1】SSR側にもCookieが必要
前回まではCSR(Client Side Rendering)を前提としたCookieの話。今の状態では、SSR(Server Side Rendering)のページは認証エラー扱いとなり動かない。これを確認してみる。
■動作確認のための準備
細かなエラー処理などは省略。
【/pages/index.tsx】:リンクを追加
import Link from 'next/link'
import Layout from '../components/Layout'
const IndexPage = () => (
<Layout title="Home | Next.js + TypeScript Example">
<h1>Hello Next.js 👋</h1>
<p>
<Link href="/about">
<a>About</a>
</Link>
</p>
<div>
<Link href="/csrpeople">
<a>CSRpeople</a>
</Link>
</div>
</Layout>
)
export default IndexPage
【./pages/csrpeople.tsx】:クライアント側でデータフェッチをするページ
import axios from "axios";
import useSWR from "swr";
const CsrPeople =()=>{
const {data,error} = useSWR(
'http://localhost:3000/api/people',
(url:string)=> axios(url).then(res => res.data)
);
console.log(data);
return(
<div>
<h1>Client Side Rendering</h1>
{JSON.stringify(data,null,4)}
</div>
);
}
export default CsrPeople
↓ 未/login状態での挙動確認
【./pages/ssrpeople.tsx】:サーバサイドレンダリングのページ
import { GetServerSideProps } from "next";
interface Person{
id:number;
name:string;
email:string;
}
//SsrPeopleコンポーネントがうけつけるpropsの型
interface PeopleProps {
people:Person[]
}
const SsrPeople =({people}:PeopleProps)=>{
return (
<div>
<h1>SSR rendering </h1>
{JSON.stringify(people,null,4)}
</div>
);
}
export default SsrPeople
export const getServerSideProps:GetServerSideProps = async (ctx)=>{
const cookie = ctx.req?.headers.cookie;
const res = await fetch('http://localhost:3000/api/people',
{
headers:{
cookie:cookie!
}
}
);
const people = await res.json();
return {props:{people}};
}
↓ 未/login状態での挙動確認
この時点ではどちらも未/login状態で認証エラーをだす。次に/loginで認証してみる。(認証したJWTをCookieにセットしてブラウザに入れる)
■/loginで認証(Cookieをブラウザにいれる)して再確認
↓
■CSR側のページ【./pages/csrpeople.tsx】の動作
■SSR側のページ【./pages/ssrpeople.tsx】の動作
あくまでクライアント側であるブラウザがCookieを持っているだけで、SSR側は発行されたCookieを持っていない。その結果、サーバサイドでデータフェッチをしにいっているが、認証エラーを返されてしまう。
【2】SSR側にCookie情報をセットする
SSRする際にもリクエストヘッダにCookieは存在しているので、これを取り出してfetch関数のheaderにセットすればよい。
【./pages/ssrpeople.tsx】
import { GetServerSideProps } from "next";
interface Person{
id:number;
name:string;
email:string;
}
//SsrPeopleコンポーネントがうけつけるpropsの型
interface PeopleProps {
people:Person[]
}
const SsrPeople =({people}:PeopleProps)=>{
return (
<div>
<h1>SSR rendering </h1>
{JSON.stringify(people,null,4)}
</div>
);
}
export default SsrPeople
export const getServerSideProps:GetServerSideProps = async (ctx)=>{
const cookie = ctx.req?.headers.cookie;
const res = await fetch('http://localhost:3000/api/people',
{
headers:{
cookie:cookie!
}
}
);
const people = await res.json();
return {props:{people}};
}
・動作確認
■その他
Cookie処理のヘルパーとして例えば「nookies」がある。Cookie処理にはこのようなライブラリを使うと楽になる。
なお、httpOnly属性が「true」の場合は、JavaScriptからアクセスできなくなる、ということを覚えておこう。
Cookieの値をとれない、操作できない、という場合にこれが原因であることもありえる。うっかり忘れてて何時間も悩む、なんてことにならないようにしよう。
もっと応援したいなと思っていただけた場合、よろしければサポートをおねがいします。いただいたサポートは活動費に使わせていただきます。