Basic 認証を付ける

受託開発などの形態の場合は結構必要になることがあるかと思います。このページでは、next実行で何かしらのページが表示されるまでの構築は済んでいるものとします。

仕組み

NextJS のページとなるコンポーネントにはgetInitialPropsというライフサイクル関数を置けます。この関数は初回(最初にページを開く時)はサーバーサイド側で実行され、引数に様々な値の入ったctxを受け取ります。
サーバーサイドの時のみこのctxにはrequestIncomingMessage)とresponseServerResponse)が含まれるので、それらで Basic 認証を実装します。

あるぺージコンポーネントPagegetInitialPropsを以下のように実装します。

const USER_PASS = 'nju33:secret'

const sendUnauthorized = res => {
  res.writeHead(401, {
    'www-authenticate': 'Basic realm=secret string'
  });
  res.end();
};

Page.getInitialProps = ({req, res}) => {
  if (!process.browser) {
    const authorization = req.headers['authorization'];

    if (typeof authorization === 'undefined') {
      sendUnauthorized(res);
      return;
    }

    const matches = authorization.match(/[^\s]+$/);
    if (matches === null) {
      sendUnauthorized(res);
      return;
    }

    const userPass = Buffer.from(
      matches[0],
      'base64'
    ).toString();

    if (userPass !== USER_PASS) {
      sendUnauthorized(res);
      return;
    }
  }

  return {message: 'foo'};
};

export default Page;

これは、

  1. authorizationが無い時はwww-authenticateを返す
  2. ある時はUSER_PASSと値を比較し、同じじゃないなら再度www-authenticateを返す
  3. 同じならpropsとなるオブジェクトを返す

のようなことをやってます。

うまくいくと画像のようになるはずです。

リポジトリ

コードはココに置いてます。