🔢

Node.jsでのDiscord OAuth2 トークン取得失敗の解決法

2024/03/09に公開

問題

Node.jsアプリケーションでDiscord OAuth2を利用したユーザー認証を試みるとき、client_idを設定しているにも関わらず、期待したトークンを取得できない問題が発生している。具体的には、設定ファイルconfig.jsonには正確なclient_idが記載されているが、Google ChromeやNode.js環境でこの値を参照すると、最後の数桁が変わってしまう。

config.json
{
    "client_id": 1215565679034638346
}

Google ChromeやNode.jsでの結果:

> 1215565679034638346
1215565679034638300

しかし、Python環境では期待通りの値が保持されている。

>>> 1215565679034638346
1215565679034638346

原因

この問題の根本的な原因はJavaScriptが扱うことができる最大整数値に関連している。JavaScriptにおける安全な最大整数値はNumber.MAX_SAFE_INTEGERで、これは9007199254740991である。Node.jsもJavaScriptのランタイム環境の一つであるため、この限界値を超える大きな整数は正確に扱えない。そのため、client_idのように大きな整数を扱う際には、精度の損失が生じ、予期しない値になる。

解決方法

この問題を解決するためには、大きな整数を正確に扱える形式でclient_idを保存することが推奨される。Node.jsでは、以下の2つの方法が考えられる。

  1. 文字列としてclient_idを保存する

    config.json内でclient_idを文字列として保存する。

    config.json
    {
        "client_id": "1215565679034638346"
    }
    

    これにより、Node.jsアプリケーションがconfig.jsonからclient_idを読み込むとき、整数ではなく文字列として扱われるため、精度の損失を避けることができる。

  2. BigIntを利用する

    もしclient_idを数値として扱いたい場合、JavaScriptのBigInt型が利用可能である。BigIntは任意の大きさの整数を正確に扱える新しい型である。

    const clientId = BigInt("1215565679034638346");
    

    BigIntを利用することで、client_idのような大きな数値も正確に扱うことができる。ただし、BigIntを利用する場合は、それをサポートするAPIやライブラリを使用していることを確認する必要がある。

これらの方法を用いれば、Node.jsでDiscord OAuth2トークン取得時のclient_id問題を解決できる。

Discussion