技術とかの雑なToday I Learnedメモ

Next.js の Edge Runtime では Buffer.from().toString() じゃなくて atob() を使えと書いてある件

Next.js の Edge Runtime では Buffer.from().toString() じゃなくて atob() を使えと書いてある件

Next.jsのMiddleware(Basic認証)を触ってみた

以前middlewareでBASIC認証を実装する記事について書いた(6/14)

実際にBASIC認証をexampleどおりに実装してデプロイしたら問題なく動いてめちゃくちゃ簡単ですごいとなったんだけど、ほんの半年前くらいの記事と直近のexampleの一部のコードが違ったのでそこの部分の話。

↑の記事からコードを引用すると、

const auth = basicAuth.split(' ')[1]
const [user, password] = Buffer.from(auth, 'base64').toString().split(':')

ここの部分。

examples/middleware.ts at main · vercel/examples

↑だと、

const authValue = basicAuth.split(' ')[1]
const [user, pwd] = atob(authValue).split(':')

になっている。

Next.js BASIC認証とかでググっても大半の記事は前者の書き方で書いてある。

本家のコミット履歴を追うと、5/5にマージされてるみたい。

basic-password | Remove the use of Buffer module for atob by louisgv · Pull Request #247 · vercel/examples

Remove the use of Buffer module for atob (#247) · vercel/examples@e7170e0

Buffer.from().toString() vs atob()

Next.jsのEdge Runtimeのページでもatob()のほうだけが書いてある。

Edge Runtime | Next.js

が、VS Codeではatob()を使うと怒られるんですよね。

じゃあそもそもこいつらは何?という話なんだけど、

Buffer | Node.js v18.4.0 Documentation

Creates a new Buffer containing string. The encoding parameter identifies the character encoding to be used when converting string into bytes.

DeepLさんによると

文字列を含む新しい Buffer を作成する。encodingパラメータは、stringをbyteに変換する際に使用する文字エンコーディングを指定する。

ということらしい。

Base64 エンコード・デコードを行う方法 - Node.js を用いた開発 - Node.js 入門

この記事によると、

HTTP の基本認証ではユーザー名とパスワードの組み合わせを HTTP ヘッダ (Authorization ヘッダ) に設定することになっています。 このときにパスワードには様々な記号も受け付けなければいけないので、なんでもセットできるように "ユーザー名:パスワード" という組み合わせを作ったら、 それを Base64 エンコードすることになっています。

なるほど、ユーザー名:パスワードをBase64エンコードしてリクエストヘッダーに付与する必要があり、Buffer.form().toString() や atob() を使ってそのヘッダー(Authorizationヘッダー)からデコードしているということか。

Buffer.from() は第一引数に渡された文字列データを第二引数に渡されたエンコーディングでデコードするというやつっぽい。

atob() はというと

WindowOrWorkerGlobalScope.atob() - Web API | MDN

Base64でのデコードをする関数らしい。

挙動は同じだけどな〜なにが違うんだろう。

Remove the use of Buffer module for atob (#247) · vercel/examples@e7170e0

このコメントにもあるように、自分の手元ではVS Codeからatob() が怒られた。

This function is only provided for compatibility with legacy web platform APIs and should never be used in new code, because they use strings to represent binary data and predate the introduction of typed arrays in JavaScript. For code running using Node.js APIs, converting between base64-encoded strings and binary data should be performed using Buffer.from(str, 'base64') and buf.toString('base64').

DeepLさんに投げた↓

この関数は、レガシーなウェブプラットフォームのAPIとの互換性のためにのみ提供されており、新しいコードでは決して使用してはいけません。なぜなら、これらはバイナリデータを表すために文字列を使用し、JavaScriptに型付き配列が導入されるよりも前のものだからです。Node.jsのAPIを使用しているコードでは、Buffer.from(str, 'base64')とbuf.toString('base64')を使用して、base64エンコード文字列とバイナリデータ間の変換を実行する必要があります。

とのことだけど、なんで atob() にわざわざ書き換えられたんだ……?