web-dev-qa-db-ja.com

passport-jwtによるノードAPIの認証

Passport-jwtを使用してJWT認証をセットアップしようとしています。私は正しい手順を実行したと思いますが、テストGETは成功せず、デバッグする方法がわかりません。

これが私がやったことです:

  1. セットアップ ドキュメントから直接passport-jwt 可能な限り

    var jwtOptions = {
        secretOrKey: 'secret',
        issuer: "accounts.examplesoft.com",  // wasn't sure what this was, so i left as defaulted in the doc
        audience: "yoursite.net"   // wasn't sure what this was, so i left as defaulted in the doc
      };
    
    jwtOptions.jwtFromRequest = ExtractJwt.fromAuthHeader();
    
    passport.use(new JwtStrategy(jwtOptions, function(jwt_payload, done) {
      User.findOne({id: jwt_payload.sub}, function(err, user) {
        if (err) {
            return done(err, false);
        }
        if (user) {
            done(null, user);
        } else {
            done(null, false);
            // or you could create a new account
        }
      });
    }));
    
  2. ユーザー/ログインエンドポイントにトークンの結果を追加しました

    var jwt = require('jsonwebtoken');
    // ...
    
    exports.postLogin = function(req, res, next) {
      passport.authenticate('local', function(err, user, info) {
        if (err) throw err;
        if (!user) {
            return res.send({ msg: 'Login incorrect' });
        }
        req.logIn(user, function(err) {
            if (err) throw err;
            var secretOrKey = jwtOptions.secretOrKey;
            var token = jwt.sign(user, secretOrKey, {
                expiresIn: 631139040 // 20 years in seconds
            });
            res.send({ user: user, jwtToken: "JWT " + token });
        });
      })(req, res, next);
    };
    

ここまでは順調だった。 (パスポートローカル認証を使用して)ユーザーをログインでき、応答は期待どおりでした...

{"user":{"_id": "56c8b5bd80d16ef41ec705dd"、 "email": "[email protected]"、 "password": "$ 2a $ 10 $ zd ... etc."、 "__v":0、} 、「jwtToken」:「JWT eyJ0eXAiOiJ ....など」 }

このように保護されていないテストルートを作成しました...

// in my routes file
app.get('/user/tokenTest', user.tokenTest);

そして、私のコントローラーでは、単純なエンドポイント...

exports.tokenTest = function(req, res) {
    console.log(req.headers);
    res.send("token test!!");
};

また、GET-ingも正常に機能します。

  1. しかし、私は次のようにそのルートを保護しようとします:

    app.get('/user/tokenTest', passport.authenticate('jwt', { session: false }),
        user.tokenTest);
    

私がそれをした後、悲しみだけです。私はこのようなリクエストを送信します:

curl -k 'https://localhost:3443/user/tokenTest' -H 'Authorization: JWT eyJ0eXAiOiJ... etc.' 

そして常に、常に401を取得します:

無許可

コントローラのコンソールログは実行されていないようです。passport.use戦略メソッド。私は微調整を繰り返してきましたが、少し迷っています。 passport-jwt docは例を提供するだけで、他のヘルプは事実上ありません。

上記で私が犯している間違い、または少なくともデバッグ方法についてのアイデアはありますか?

14
user1272965

ここで私に続く貧しい魂のために:passport-jwt docは、authヘッダーがこのように見えるべきであることを暗示しています...

承認:JWT JSON_WEB_TOKEN_STRING .....

それは誤解を招くことがわかりました(とにかく私にとって)。

幸い、 この記事 のおかげで、トークンがどのように構築されるかを知ることができました。 (最初の「。」までのトークンの接頭辞は、スキームのbase64エンコーディングです。先頭の「JWT」はノイズであり、検証が機能しませんでした。

したがって、修正は、ユーザーコントローラーから返されたトークンを次のように変更することでした。

    res.send({ user: user, jwtToken: "JWT " + token });

より簡単に:

    res.send({ user: user, jwtToken: token });

ふew。それは私ですか、それとも本当にこれらのものが多くのノードパッケージドキュメントで不十分に説明されているのは残念ですか?

26
user1272965

遅れるかもしれませんが、同様の問題があり、別の解決策があります。このoptions.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('JWT')を使用して、次の形式で認証ヘッダーからJWTトークンを抽出できます。

承認:JWT JSON_WEB_TOKEN_STRING .....

これが私が使用したドキュメントです: https://github.com/themikenicholson/passport-jwt

リクエストからJWTを抽出する

JWTをリクエストに含める方法はいくつかあります。可能な限り柔軟性を維持するために、JWTは、jwtFromRequestパラメーターとして渡されるユーザー指定のコールバックによってリクエストから解析されます。このコールバックは、今後エクストラクターと呼ばれ、リクエストオブジェクトを引数として受け入れ、エンコードされたJWT文字列またはnullを返します。含まれるエクストラクター

Passport-jwt.ExtractJwtには、いくつかの抽出ファクトリー関数が用意されています。これらのファクトリー関数は、指定されたパラメーターで構成された新しいエクストラクターを返します。

fromHeader(header_name) creates a new extractor that looks for the JWT in the given http header
fromBodyField(field_name) creates a new extractor that looks for the JWT in the given body field. You must have a body parser configured in order to use this method.
fromUrlQueryParameter(param_name) creates a new extractor that looks for the JWT in the given URL query parameter.
fromAuthHeaderWithScheme(auth_scheme) creates a new extractor that looks for the JWT in the authorization header, expecting the scheme to match auth_scheme.
fromAuthHeaderAsBearerToken() creates a new extractor that looks for the JWT in the authorization header with the scheme 'bearer'
fromExtractors([array of extractor functions]) creates a new extractor using an array of extractors provided. Each extractor is attempted in order until one returns a token.
0
Bruno Tavares