建てる | 依存 |
---|---|
JSON Web トークンの実装。
これはdraft-ietf-oauth-json-web-token-08
に対して開発されました。それはnode-jwsを利用します
$ npm install jsonwebtoken
v8 から v9 へ
v7 から v8 へ
(非同期) コールバックが指定された場合、コールバックはerr
または JWT で呼び出されます。
(同期) JsonWebToken を文字列として返します。
payload
有効な JSON を表すオブジェクト リテラル、バッファ、または文字列です。
exp
またはその他のクレームは、ペイロードがオブジェクト リテラルの場合にのみ設定されることに注意してください。バッファーまたは文字列ペイロードの JSON 有効性はチェックされません。
payload
バッファまたは文字列でない場合は、JSON.stringify
使用して文字列に強制変換されます。
secretOrPrivateKey
は、HMAC アルゴリズムのシークレット、または RSA および ECDSA の PEM エンコードされた秘密キーを含む文字列 (utf-8 エンコード)、バッファ、オブジェクト、または KeyObject です。パスフレーズを持つ秘密キーの場合、オブジェクト{ key, passphrase }
を使用できます (暗号化ドキュメントに基づく)。この場合は、必ずalgorithm
オプションを渡してください。 RSA アルゴリズムで署名する場合、allowInsecureKeySizes オプションが true に設定されている場合を除き、最小モジュラス長は 2048 です。このサイズ未満の秘密キーはエラーで拒否されます。
options
:
algorithm
(デフォルト: HS256
)
expiresIn
: 秒単位、または時間範囲を表す文字列 (vercel/ms) で表されます。
例:
60
、"2 days"
、"10h"
、"7d"
。数値は秒数として解釈されます。文字列を使用する場合は、必ず時間単位 (日、時間など) を指定してください。それ以外の場合は、デフォルトでミリ秒単位が使用されます ("120"
は"120ms"
と同じです)。
notBefore
: 秒単位、または時間範囲を表す文字列 (vercel/ms) で表されます。
例:
60
、"2 days"
、"10h"
、"7d"
。数値は秒数として解釈されます。文字列を使用する場合は、必ず時間単位 (日、時間など) を指定してください。それ以外の場合は、デフォルトでミリ秒単位が使用されます ("120"
は"120ms"
と同じです)。
audience
issuer
jwtid
subject
noTimestamp
header
keyid
mutatePayload
: true の場合、sign 関数はペイロード オブジェクトを直接変更します。これは、クレームが適用された後、トークンにエンコードされる前に、ペイロードへの生の参照が必要な場合に便利です。
allowInsecureKeySizes
: true の場合、2048 未満のモジュラスを持つ秘密キーを RSA に使用できるようにします。
allowInvalidAsymmetricKeyTypes
: true の場合、指定されたアルゴリズムに一致しない非対称キーを許可します。このオプションは下位互換性のみを目的としており、使用しないでください。
expiresIn
、notBefore
、audience
、subject
、issuer
にはデフォルト値はありません。 これらのクレームは、それぞれexp
、nbf
、aud
、sub
、iss
を使用してペイロードに直接指定することもできますが、両方の場所に含めることはできません。
exp
、 nbf
、およびiat
NumericDateであることに注意してください。関連するトークンの有効期限 (exp クレーム) を参照してください。
ヘッダーは、 options.header
オブジェクトを介してカスタマイズできます。
noTimestamp
が指定されていない限り、生成された jwt にはデフォルトでiat
(発行日) クレームが含まれます。 iat
がペイロードに挿入されると、 options.expiresIn
で指定されたタイムスパンのexp
など、他のものを計算するために実際のタイムスタンプの代わりに使用されます。
デフォルトの同期署名 (HMAC SHA256)
var jwt = require('jsonwebtoken');var token = jwt.sign({ foo: 'bar' }, 'shhhhh');
RSA SHA256 による同期署名
// RSA SHA256 で署名しますvar privateKey = fs.readFileSync('private.key');var token = jwt.sign({ foo: 'bar' }, privateKey, { Algorithm: 'RS256' });
非同期で署名する
jwt.sign({ foo: 'bar' }, privateKey, { アルゴリズム: 'RS256' }, function(err, token) { console.log(トークン);});
jwt を 30 秒バックデートする
var old_token = jwt.sign({ foo: 'bar', iat: Math.floor(Date.now() / 1000) - 30 }, 'shhhhh');
JWT の標準では、有効期限のexp
クレームが定義されています。有効期限はNumericDateとして表されます。
1970-01-01T00:00:00Z UTC から指定された UTC 日付/時刻までの秒数を表す JSON 数値 (閏秒を無視)。 これは、IEEE Std 1003.1, 2013 Edition [POSIX.1] の定義「エポック以降の秒数」と同等です。この定義では、非整数値を表現できることを除けば、毎日が正確に 86400 秒で計算されます。 一般的な日付/時刻、特に UTC に関する詳細については、RFC 3339 [RFC3339] を参照してください。
これは、 exp
フィールドにエポックからの秒数を含める必要があることを意味します。
有効期限が 1 時間のトークンに署名する:
jwt.sign({ exp: Math.floor(Date.now() / 1000) + (60 * 60), データ: 'foobar'}, 'secret');
このライブラリを使用してこのようなトークンを生成する別の方法は次のとおりです。
jwt.sign({ data: 'foobar'}, 'secret', {expiresIn: 60 * 60 });//またはさらに良い:jwt.sign({ データ: 'foobar'}, 'secret', { 有効期限: '1h' });
(非同期) コールバックが指定された場合、関数は非同期的に動作します。署名が有効で、オプションの有効期限、対象者、または発行者が有効な場合、デコードされたペイロードを使用してコールバックが呼び出されます。そうでない場合は、エラーが発生して呼び出されます。
(同期) コールバックが指定されていない場合、関数は同期的に動作します。署名が有効で、オプションの有効期限、対象者、または発行者が有効な場合は、デコードされたペイロードを返します。そうでない場合は、エラーがスローされます。
警告:トークンが信頼できないソース (ユーザー入力や外部リクエストなど) から来た場合、返されたデコードされたペイロードは他のユーザー入力と同様に扱われる必要があります。必ずサニタイズし、期待されるプロパティのみを操作してください。
token
JsonWebToken 文字列です
secretOrPublicKey
は、HMAC アルゴリズムのシークレット、または RSA および ECDSA の PEM エンコードされた公開キーを含む文字列 (utf-8 エンコード)、バッファ、または KeyObject です。 jwt.verify
が非同期で呼び出される場合は、 secretOrPublicKey
秘密鍵または公開鍵をフェッチする関数にすることができます。詳細な例については以下を参照してください
このコメントで述べたように、base64 でエンコードされたシークレット (base64 を使用してエンコードされたランダムなバイト) を期待する他のライブラリがあります。その場合はBuffer.from(secret, 'base64')
渡すことができます。これにより、シークレットがデコードされます。 Base64 を使用し、トークン検証には元のランダム バイトが使用されます。
options
algorithms
: 許可されたアルゴリズムの名前を含む文字列のリスト。たとえば、 ["HS256", "HS384"]
です。
指定しない場合は、提供されたキーのタイプに基づいてデフォルトが使用されます。
シークレット - ['HS256'、'HS384'、'HS512'】
rsa - ['RS256'、'RS384'、'RS512'】
ec - ['ES256'、'ES384'、'ES512']
デフォルト - ['RS256'、'RS384'、'RS512'】
audience
: オーディエンス ( aud
) を確認する場合は、ここに値を指定します。オーディエンスは、文字列、正規表現、または文字列や正規表現のリストに対してチェックできます。
例:
"urn:foo"
、/urn:f[o]{2}/
、[/urn:f[o]{2}/, "urn:bar"]
complete
: ペイロードの通常の内容だけではなく、デコードされた{ payload, header, signature }
を含むオブジェクトを返します。
issuer
(オプション): iss
フィールドの有効な値の文字列または文字列の配列。
jwtid
(オプション): JWT ID ( jti
) を確認する場合は、ここに文字列値を指定します。
ignoreExpiration
: true
の場合、トークンの有効期限を検証しません。
ignoreNotBefore
...
subject
: 件名 ( sub
) を確認する場合は、ここに値を入力します。
clockTolerance
: 異なるサーバー間のわずかなクロックの違いに対処するために、 nbf
およびexp
クレームをチェックするときに許容する秒数
maxAge
: トークンがまだ有効であるために許可される最大有効期間。これは、秒、または時間範囲を表す文字列 (vercel/ms) で表されます。
例:
1000
、"2 days"
、"10h"
、"7d"
。数値は秒数として解釈されます。文字列を使用する場合は、必ず時間単位 (日、時間など) を指定してください。それ以外の場合は、デフォルトでミリ秒単位が使用されます ("120"
は"120ms"
と同じです)。
clockTimestamp
: 必要なすべての比較で現在時刻として使用される秒単位の時刻。
nonce
: nonce
クレームを確認したい場合は、ここに文字列値を指定します。 Open ID で ID トークンとして使用されます。 (オープンID導入メモ)
allowInvalidAsymmetricKeyTypes
: true の場合、指定されたアルゴリズムに一致しない非対称キーを許可します。このオプションは下位互換性のみを目的としており、使用しないでください。
// トークンの対称性を検証します - synchronousvar decoded = jwt.verify(token, 'shhhah');console.log(decoded.foo) // bar// トークンの対称性を検証しますjwt.verify(token, 'shhhah', function(err) 、デコードされた) { console.log(decoded.foo) // bar});// 無効なトークン - synchronoustry { var decoded = jwt.verify(token, '間違った秘密');} catch(err) { // エラー}// 無効な tokenjwt.verify(token, 'wrong-secret', function(err, decoded) { // エラー // デコードされた unknown});// トークンを検証する asymmetricvar cert = fs.readFileSync('public.pem'); // 公開鍵を取得するjwt.verify(token, cert, function(err, decoded) { console.log(decoded.foo) // bar});// 検証audiencevar cert = fs.readFileSync('public.pem'); // 公開鍵を取得jwt.verify(token, cert, {audience: 'urn:foo' }, function(err, decoded) { // オーディエンスが一致しない場合、err == 無効なオーディエンス});// issuervar cert = fs.readFileSync('public.pem'); を確認します。 // 公開鍵を取得するjwt.verify(token, cert, { 対象者: 'urn:foo', 発行者: 'urn:issuer' }, function(err, decoded) { // 発行者が一致しない場合、err == 無効な発行者});// jwt idvar cert = fs.readFileSync('public.pem'); を確認します。 // 公開鍵を取得するjwt.verify(token, cert, { 対象者: 'urn:foo', 発行者: 'urn:issuer', jwtid: 'jwtid' }, function(err, decoded) { // jwt id が一致しない場合、err == 無効な jwt id});// subjectvar cert = fs.readFileSync('public.pem'); を確認します。 // 公開鍵を取得するjwt.verify(token, cert, { 対象者: 'urn:foo', 発行者: 'urn:issuer', jwtid: 'jwtid', subject: 'subject' }, function(err, decoded) { // 件名が一致しない場合、err == 無効な件名});// alg missmatchvar cert = fs.readFileSync('public.pem'); // 公開鍵を取得するjwt.verify(token, cert, { アルゴリズム: ['RS256'] }, function (err, payload) { // if トークン alg != RS256、err == 無効な署名});// getKey コールバックを使用して確認する// 例では、キーをフェッチする方法として https://github.com/auth0/node-jwks-rsa を使用します。 var jwksClient = require('jwks-rsa');var client = jwksClient({ jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json'});function getKey(header, callback){ client.getSigningKey(header.kid, function(err, key) {var signedKey = key.publicKey || key.rsaPublicKey;callback(null, signedKey); });}jwt.verify(トークン、getKey、オプション、関数(エラー、デコード) { console.log(decoded.foo) // bar});
(同期) 署名が有効かどうかを検証せずに、デコードされたペイロードを返します。
警告:これでは、署名が有効かどうかは検証されません。信頼できないメッセージにはこれを使用しないでください。代わりに
jwt.verify
使用することをお勧めします。
警告:トークンが信頼できないソース (ユーザー入力や外部リクエストなど) から来た場合、返されたデコードされたペイロードは他のユーザー入力と同様に扱われる必要があります。必ずサニタイズし、期待されるプロパティのみを操作してください。
token
JsonWebToken 文字列です
options
:
json
: ヘッダーに"typ":"JWT"
が含まれていない場合でも、ペイロードで JSON.parse を強制します。
complete
: デコードされたペイロードとヘッダーを含むオブジェクトを返します。
例
// 署名を無視してデコードされたペイロードを取得します。secretOrPrivateKey は必要ありませんvar decoded = jwt.decode(token);// デコードされたペイロードと headervar を取得します decoded = jwt.decode(token, {complete: true});console.log(decoded.ヘッダー);console.log(デコードされた.ペイロード)
検証中にエラーがスローされる可能性があります。 Error は検証コールバックの最初の引数です。
トークンの有効期限が切れている場合は、エラーがスローされます。
エラーオブジェクト:
名前: 'トークン期限切れエラー'
メッセージ: 「JWT の有効期限が切れました」
期限切れ: [期限切れ]
jwt.verify(トークン, 'シーッ', 関数(エラー, デコード) { if (err) {/* err = { 名前: 'TokenExpiredError'、メッセージ: 'jwt 期限切れ'、expiredAt: 1408621000 } */ }});
エラーオブジェクト:
名前: 'JsonWebTokenError'
メッセージ:
「無効なトークン」 - ヘッダーまたはペイロードを解析できませんでした
「jwt malformed」 - トークンに 3 つのコンポーネント ( .
で区切られた) がありません。
「jwt署名が必要です」
「無効な署名」
'jwt オーディエンスが無効です。予想される内容: [OPTIONS AUDIENCE]'
'jwt 発行者が無効です。予想される内容: [オプション発行者]'
'jwt ID が無効です。予想される内容: [OPTIONS JWT ID]'
'jwt 件名が無効です。期待される内容: [オプションの件名]'
jwt.verify(トークン, 'シーッ', 関数(エラー, デコード) { if (err) {/* err = { 名前: 'JsonWebTokenError'、メッセージ: 'jwt 不正な形式' } */ }});
現在時刻が nbf クレームより前の場合にスローされます。
エラーオブジェクト:
名前: 'NotBeforeError'
メッセージ: 「jwt がアクティブではありません」
日付: 2018-10-04T16:10:44.000Z
jwt.verify(トークン, 'シーッ', 関数(エラー, デコード) { if (err) {/* err = { 名前: 'NotBeforeError'、メッセージ: 'jwt がアクティブではありません'、日付: 2018-10-04T16:10:44.000Z } */ }});
サポートされているアルゴリズムの配列。現在、次のアルゴリズムがサポートされています。
alg パラメータ値 | デジタル署名または MAC アルゴリズム |
---|---|
HS256 | SHA-256 ハッシュ アルゴリズムを使用した HMAC |
HS384 | SHA-384 ハッシュ アルゴリズムを使用した HMAC |
HS512 | SHA-512 ハッシュ アルゴリズムを使用した HMAC |
RS256 | SHA-256 ハッシュ アルゴリズムを使用した RSASSA-PKCS1-v1_5 |
RS384 | SHA-384 ハッシュ アルゴリズムを使用した RSASSA-PKCS1-v1_5 |
RS512 | SHA-512 ハッシュ アルゴリズムを使用した RSASSA-PKCS1-v1_5 |
PS256 | SHA-256 ハッシュ アルゴリズムを使用する RSASSA-PSS (ノード ^6.12.0 または >=8.0.0 のみ) |
PS384 | SHA-384 ハッシュ アルゴリズムを使用する RSASSA-PSS (ノード ^6.12.0 または >=8.0.0 のみ) |
PS512 | SHA-512 ハッシュ アルゴリズムを使用する RSASSA-PSS (ノード ^6.12.0 または >=8.0.0 のみ) |
ES256 | P-256 曲線と SHA-256 ハッシュ アルゴリズムを使用した ECDSA |
ES384 | P-384 曲線と SHA-384 ハッシュ アルゴリズムを使用した ECDSA |
ES512 | P-521 曲線と SHA-512 ハッシュ アルゴリズムを使用した ECDSA |
なし | デジタル署名または MAC 値は含まれていません |
まず、JWT の自動更新によってシステムに脆弱性がもたらされないかどうかを慎重に検討することをお勧めします。
これをライブラリの一部として含めることには抵抗がありますが、これをどのように実現できるかを示すためにこの例を見てください。この例とは別に、このトピックに関する詳細な情報を取得するためのイシューとプル リクエストがあります。
X.509 証明書チェーンがチェックされていない
バグを見つけた場合、または機能リクエストがある場合は、このリポジトリの問題セクションで報告してください。公開されている GitHub 問題トラッカーでセキュリティの脆弱性を報告しないでください。責任ある開示プログラムには、セキュリティ問題を開示する手順が詳しく記載されています。
認証0
このプロジェクトは MIT ライセンスに基づいてライセンスされています。詳細については、LICENSE ファイルを参照してください。