質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.52%

  • Node.js

    1857questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

  • Authentication

    86questions

    Authentication(認証)は正当性を認証する為の工程です。ログイン処理等で使われます。

node auth0 jwtの検証が失敗する

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 319

pokotyan

score 4

auth0(https://auth0.com/)を使ってjwtを用いたログイン機能を作っています。
ログイン、ログアウト自体は正常にできるのですが、作成されたjwtをverifyメソッドで検証すると下記のエラーが返って来ます。

JsonWebTokenError {name: "JsonWebTokenError", message: "invalid algorithm", stack: "JsonWebTokenError: invalid algorithm↵    at eval (…ode_modules/redux-saga/es/internal/proc.js:398:7)"}

verifyメソッド
https://github.com/auth0/node-jsonwebtoken#jwtverifytoken-secretorpublickey-options-callback

作成されたjwtはjwt.io(https://jwt.io/)のencodedに入れると正常にデコードされます。

コードは以下です。

// auth0の管理画面のClient Secretの値を環境変数AUTH0_SECRETに入れています。
var secret = new Buffer(process.env.AUTH0_SECRET, 'base64');

// jwtはローカルストレージにid_tokenという名前で保存しています。
jwt.verify(localStorage.getItem('id_token'), secret, (err, decoded) => {
  console.log(err); // JsonWebTokenErrorが発生する
  console.log(decoded);
});

// jwtのデコードはちゃんとできる
const decode = jwt.decode(localStorage.getItem('id_token')); // no error

何か原因がわかりますでしょうか?
よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

check解決した方法

0

jwtの署名のアルゴリズムにRS256を用いている場合は公開鍵を用いて検証を行う必要があるらしく、以下のurlを参考にしたところ検証が成功するようになりました。

https://auth0.com/blog/navigating-rs256-and-jwks/
https://github.com/sgmeyer/auth0-node-jwks-rs256

auth0のjwks(https://auth0.com/docs/jwks)のエンドポイントを叩くと手に入るx5cを用いて、公開鍵を生成し、それをjwt.verifyの引数に渡したところ、検証が通るようになりました。

    const token = jwt.decode(localStorage.getItem('id_token'), {
      complete: true
    });
    const { kid } = token.header;
    const { data: jwks } = yield axios.get(
      `https://${process.env.AUTH0_DOMAIN}/.well-known/jwks.json`
    );

    let cert;
    const jwksKey = jwks.keys.find(key => key.kid === kid); //デコードされたjwtのkidとjwksのkidが一致するものを取得
    cert = jwksKey.x5c[0];
    cert = cert.match(/.{1,64}/g).join('\n');
    cert = `-----BEGIN CERTIFICATE-----\n${cert}\n-----END CERTIFICATE-----\n`;

    jwt.verify(localStorage.getItem('id_token'), cert, (err, decoded) => {
      console.log(err);
      console.log(decoded); // no error
    });

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

私の手元ですと以下のようなコードでも問題なく decoded が取得できました。

jwt.verify(localStorage.getItem('id_token'), process.env.AUTH0_SECRET, (err, decoded) => {
  console.info(err)
  console.info(decoded)
})

おそらく、引数の secret がBufferのインスタンスのまま渡しているのが問題かなと思います。したがって、引数を以下のように文字列に変換して渡すとどうでしょうか?

- jwt.verify(localStorage.getItem('id_token'), secret, (err, decoded) => {
+ jwt.verify(localStorage.getItem('id_token'), secret.toString('base64'), (err, decoded) => {

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/19 15:56

    ご回答ありがとうございます!
    どうやらsecretの値で検証をするのは署名のアルゴリズムがHS256の場合のようでした。
    https://auth0.com/docs/api-auth/tutorials/verify-access-token#how-can-i-verify-the-signature-

    キャンセル

  • 2018/07/19 16:02

    なるほど、理解しました。勉強になりました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Node.js

    1857questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

  • Authentication

    86questions

    Authentication(認証)は正当性を認証する為の工程です。ログイン処理等で使われます。