Next.jsで簡易的なアクセス制限機能を実装するときに、アクセス接続元情報を参照する必要があった。
簡易的なアクセス制限機能であるため、クライアントを識別するには次の情報さえあれば良い。
(厳密にやるならばネットワーク上にサーバ等構築する必要はある。)
- IPアドレス
- User Agent
- ホスト名
これらの接続元情報をNext.jsで構築したアプリケーションで取得する方法について書く。
環境
- Next.js 12.0.4
実装
SSR(サーバーサイド)で実行されるgetServerSidePropsメソッドには、contextというオブジェクトが渡ってくる。
contextオブジェクトには、reqというリクエストオブジェクトが内包されており、リクエストヘッダーの情報も含んでいるため、前述した接続元情報はreqオブジェクトから参照する。
getServerSidePropsからreqを参照するには次のように記載する。
export const getServerSideProps: GetServerSideProps = async(context) => {
const { req } = context;
return {
props: {}
}
}
IPアドレスの取得
x-forwarded-forヘッダーからIPアドレスを参照する。
X-Forwarded-For - HTTP | MDN
x-forwarded-forヘッダーは、次のようにカンマ区切りの構造となっている。
X-Forwarded-For: <client>, <proxy1>, <proxy2>
proxyには、複数のプロキシを経由された場合に経由されたプロキシのIPアドレスが出力される。
接続元(client)のIPアドレスを取得するには、カンマ区切りしたリストの先頭を参照すれば良い。
const ipAddress = req.headers["x-forwarded-for"]
? String(req.headers["x-forwarded-for"]).split(',')[0]
: req.connection.remoteAddress
? req.connection.remoteAddress
: "";
User Agentの取得
User-AgentヘッダーからUser Agentを参照する。
User-Agent - HTTP | MDN
const userAgent = req.headers["user-agent"];
ホスト名の取得
ホスト名はHTTPヘッダーには含まれないため、IPアドレスから逆引きして取得する。
Node.jsのdns.lookupServiceメソッドを使用してDNSサーバに問い合わせを行う。
import {lookupService} from "dns";
const getHostName = (ipAddress: string): Promise<string> => {
return new Promise(function(resolve, reject) {
lookupService(ipAddress, 22, function (error, hostname, service) {
if (error) {
return reject(error);
}
resolve(hostname);
});
});
};
const hostName = await getHostName(ipAddress);
dns.lookupServiceメソッドは、問い合わせ成功時にコールバック関数を介してホスト名を返却する。
任意の変数などに初期化するには、Promiseオブジェクトでラップして返却させる。