express-jwt vs express-jwt-authz vs jsonwebtoken vs jwt-simple vs koa-jwt vs passport-jwt
JWT認証ライブラリ
express-jwtexpress-jwt-authzjsonwebtokenjwt-simplekoa-jwtpassport-jwt類似パッケージ:

JWT認証ライブラリ

JWT(JSON Web Token)認証ライブラリは、Webアプリケーションにおいてユーザーの認証と認可を管理するためのツールです。これらのライブラリは、トークンを生成、検証、管理するための機能を提供し、セキュアなAPIアクセスを実現します。これにより、ユーザーは安全にリソースにアクセスでき、サーバーはユーザーの身元を確認することができます。

npmのダウンロードトレンド

3 年

GitHub Starsランキング

統計詳細

パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
express-jwt04,51228.5 kB641年前MIT
express-jwt-authz0987.75 kB6-MIT
jsonwebtoken018,17343.4 kB2006ヶ月前MIT
jwt-simple01,360-347年前MIT
koa-jwt01,34943.2 kB6-MIT
passport-jwt01,98252 kB43-MIT

機能比較: express-jwt vs express-jwt-authz vs jsonwebtoken vs jwt-simple vs koa-jwt vs passport-jwt

トークン生成

  • express-jwt:

    express-jwtは、JWTの検証に特化しており、トークンの生成機能は提供しません。

  • express-jwt-authz:

    express-jwt-authzもトークン生成機能は持たず、主にアクセス制御に焦点を当てています。

  • jsonwebtoken:

    jsonwebtokenは、トークンの生成と検証の両方をサポートしており、カスタマイズ可能なペイロードを持つトークンを生成できます。

  • jwt-simple:

    jwt-simpleは、シンプルなAPIを使用してトークンを生成することができ、基本的な機能を提供します。

  • koa-jwt:

    koa-jwtは、トークンの生成機能を持たず、主にトークンの検証に使用されます。

  • passport-jwt:

    passport-jwtは、Passportの戦略としてJWTを使用するため、トークンの生成は他のPassport戦略に依存します。

アクセス制御

  • express-jwt:

    express-jwtは、JWTの検証を行うだけで、アクセス制御の機能は持っていません。

  • express-jwt-authz:

    express-jwt-authzは、ロールベースのアクセス制御を実現し、ユーザーの権限に基づいてリソースへのアクセスを制限します。

  • jsonwebtoken:

    jsonwebtokenは、トークンの検証を行うため、アクセス制御の実装は別途必要です。

  • jwt-simple:

    jwt-simpleもトークンの検証を行いますが、アクセス制御の機能は持っていません。

  • koa-jwt:

    koa-jwtは、トークンの検証を行い、アクセス制御は別途実装する必要があります。

  • passport-jwt:

    passport-jwtは、Passportのフレームワークを利用して、認証とアクセス制御を統合的に管理します。

学習曲線

  • express-jwt:

    express-jwtはシンプルで、使い方が直感的なため、学習曲線は緩やかです。

  • express-jwt-authz:

    express-jwt-authzも比較的簡単ですが、ロールベースのアクセス制御の概念を理解する必要があります。

  • jsonwebtoken:

    jsonwebtokenは、トークンの生成と検証の理解が必要ですが、APIはシンプルで扱いやすいです。

  • jwt-simple:

    jwt-simpleは非常にシンプルなAPIを提供しており、学習曲線は非常に緩やかです。

  • koa-jwt:

    koa-jwtはKoa特有のミドルウェアであるため、Koaに慣れている必要がありますが、基本的な使い方は簡単です。

  • passport-jwt:

    passport-jwtはPassportの戦略として機能するため、Passportの基本を理解する必要がありますが、全体的には使いやすいです。

拡張性

  • express-jwt:

    express-jwtは、他のミドルウェアと組み合わせて使用することで、拡張性がありますが、単体では機能が限られています。

  • express-jwt-authz:

    express-jwt-authzは、express-jwtと組み合わせて使用することで、より強力なアクセス制御を実現します。

  • jsonwebtoken:

    jsonwebtokenは、トークンの生成と検証に関して非常に柔軟で、カスタマイズが可能です。

  • jwt-simple:

    jwt-simpleはシンプルさを重視しているため、拡張性は限られていますが、基本的な機能は提供します。

  • koa-jwt:

    koa-jwtはKoaフレームワークに特化しており、他のKoaミドルウェアと組み合わせて使用することで拡張できます。

  • passport-jwt:

    passport-jwtはPassportのフレームワークに統合されているため、他のPassport戦略と組み合わせて拡張性があります。

メンテナンス

  • express-jwt:

    express-jwtはシンプルな設計のため、メンテナンスが容易です。

  • express-jwt-authz:

    express-jwt-authzもシンプルですが、依存関係が増えるため、メンテナンスには注意が必要です。

  • jsonwebtoken:

    jsonwebtokenは広く使用されているため、コミュニティのサポートが充実しており、メンテナンスがしやすいです。

  • jwt-simple:

    jwt-simpleは非常にシンプルなため、メンテナンスは容易ですが、機能が限られています。

  • koa-jwt:

    koa-jwtはKoaに特化しているため、Koaのバージョンに依存しますが、メンテナンスは比較的簡単です。

  • passport-jwt:

    passport-jwtはPassportのエコシステムに依存しているため、Passportの更新に合わせてメンテナンスが必要です。

選び方: express-jwt vs express-jwt-authz vs jsonwebtoken vs jwt-simple vs koa-jwt vs passport-jwt

  • express-jwt:

    Expressフレームワークを使用している場合、express-jwtはシンプルで使いやすく、JWTの検証を行うための基本的なミドルウェアを提供します。

  • express-jwt-authz:

    より細かいアクセス制御が必要な場合、express-jwt-authzを選択してください。このライブラリは、express-jwtと組み合わせて、ロールベースのアクセス制御を実現します。

  • jsonwebtoken:

    トークンの生成や検証を手動で行いたい場合、jsonwebtokenを選択します。このライブラリは、JWTの作成と検証に特化しており、柔軟性があります。

  • jwt-simple:

    軽量なライブラリを求める場合、jwt-simpleが適しています。シンプルなAPIを提供し、基本的なJWTの生成と検証を行います。

  • koa-jwt:

    Koaフレームワークを使用している場合、koa-jwtを選択してください。Koaに特化したミドルウェアで、JWTの検証を簡単に行えます。

  • passport-jwt:

    Passport.jsを使用している場合、passport-jwtを選択します。このライブラリは、Passportの戦略としてJWTを統合し、認証プロセスを簡素化します。

express-jwt のREADME

express-jwt

This module provides Express middleware for validating JWTs (JSON Web Tokens) through the jsonwebtoken module. The decoded JWT payload is available on the request object.

Install

$ npm install express-jwt

API

expressjwt(options)

Options has the following parameters:

  • secret: jwt.Secret | GetVerificationKey (required): The secret as a string or a function to retrieve the secret.
  • getToken?: TokenGetter (optional): A function that receives the express Request and returns the token, by default it looks in the Authorization header.
  • isRevoked?: IsRevoked (optional): A function to verify if a token is revoked.
  • onExpired?: ExpirationHandler (optional): A function to handle expired tokens.
  • credentialsRequired?: boolean (optional): If its false, continue to the next middleware if the request does not contain a token instead of failing, defaults to true.
  • requestProperty?: string (optional): Name of the property in the request object where the payload is set. Default to req.auth.
  • Plus... all the options available in the jsonwebtoken verify function.

The available functions have the following interface:

  • GetVerificationKey = (req: express.Request, token: jwt.Jwt | undefined) => Promise<jwt.Secret>;
  • IsRevoked = (req: express.Request, token: jwt.Jwt | undefined) => Promise<boolean>;
  • TokenGetter = (req: express.Request) => string | Promise<string> | undefined;

Usage

Basic usage using an HS256 secret:

var { expressjwt: jwt } = require("express-jwt");
// or ES6
// import { expressjwt, ExpressJwtRequest } from "express-jwt";

app.get(
  "/protected",
  jwt({ secret: "shhhhhhared-secret", algorithms: ["HS256"] }),
  function (req, res) {
    if (!req.auth.admin) return res.sendStatus(401);
    res.sendStatus(200);
  }
);

The decoded JWT payload is available on the request via the auth property.

The default behavior of the module is to extract the JWT from the Authorization header as an OAuth2 Bearer token.

Required Parameters

The algorithms parameter is required to prevent potential downgrade attacks when providing third party libraries as secrets.

:warning: Do not mix symmetric and asymmetric (ie HS256/RS256) algorithms: Mixing algorithms without further validation can potentially result in downgrade vulnerabilities.

jwt({
  secret: "shhhhhhared-secret",
  algorithms: ["HS256"],
  //algorithms: ['RS256']
});

Additional Options

You can specify audience and/or issuer as well, which is highly recommended for security purposes:

jwt({
  secret: "shhhhhhared-secret",
  audience: "http://myapi/protected",
  issuer: "http://issuer",
  algorithms: ["HS256"],
});

If the JWT has an expiration (exp), it will be checked.

If you are using a base64 URL-encoded secret, pass a Buffer with base64 encoding as the secret instead of a string:

jwt({
  secret: Buffer.from("shhhhhhared-secret", "base64"),
  algorithms: ["RS256"],
});

To only protect specific paths (e.g. beginning with /api), use express router call use, like so:

app.use("/api", jwt({ secret: "shhhhhhared-secret", algorithms: ["HS256"] }));

Or, the other way around, if you want to make some paths unprotected, call unless like so.

app.use(
  jwt({
    secret: "shhhhhhared-secret",
    algorithms: ["HS256"],
  }).unless({ path: ["/token"] })
);

This is especially useful when applying to multiple routes. In the example above, path can be a string, a regexp, or an array of any of those.

For more details on the .unless syntax including additional options, please see express-unless.

This module also support tokens signed with public/private key pairs. Instead of a secret, you can specify a Buffer with the public key

var publicKey = fs.readFileSync("/path/to/public.pub");
jwt({ secret: publicKey, algorithms: ["RS256"] });

Customizing Token Location

A custom function for extracting the token from a request can be specified with the getToken option. This is useful if you need to pass the token through a query parameter or a cookie. You can throw an error in this function and it will be handled by express-jwt.

app.use(
  jwt({
    secret: "hello world !",
    algorithms: ["HS256"],
    credentialsRequired: false,
    getToken: function fromHeaderOrQuerystring(req) {
      if (
        req.headers.authorization &&
        req.headers.authorization.split(" ")[0] === "Bearer"
      ) {
        return req.headers.authorization.split(" ")[1];
      } else if (req.query && req.query.token) {
        return req.query.token;
      }
      return null;
    },
  })
);

Retrieve key dynamically

If you need to obtain the key dynamically from other sources, you can pass a function in the secret parameter with the following parameters:

  • req (Object) - The express request object.
  • token (Object) - An object with the JWT payload and headers.

For example, if the secret varies based on the issuer:

var jwt = require("express-jwt");
var data = require("./data");
var utilities = require("./utilities");

var getSecret = async function (req, token) {
  const issuer = token.payload.iss;
  const tenant = await data.getTenantByIdentifier(issuer);
  if (!tenant) {
    throw new Error("missing_secret");
  }
  return utilities.decrypt(tenant.secret);
};

app.get(
  "/protected",
  jwt({ secret: getSecret, algorithms: ["HS256"] }),
  function (req, res) {
    if (!req.auth.admin) return res.sendStatus(401);
    res.sendStatus(200);
  }
);

Secret rotation

The getSecret callback could also be used in cases where the same issuer might issue tokens with different keys at certain point:

var getSecret = async function (req, token) {
  const { iss } = token.payload;
  const { kid } = token.header;
  // get the verification key by a given key-id and issuer.
  return verificationKey;
};

Revoked tokens

It is possible that some tokens will need to be revoked so they cannot be used any longer. You can provide a function as the isRevoked option. The signature of the function is function(req, payload, done):

  • req (Object) - The express request object.
  • token (Object) - An object with the JWT payload and headers.

For example, if the (iss, jti) claim pair is used to identify a JWT:

const jwt = require("express-jwt");
const data = require("./data");

const isRevokedCallback = async (req, token) => {
  const issuer = token.payload.iss;
  const tokenId = token.payload.jti;
  const token = await data.getRevokedToken(issuer, tokenId);
  return token !== "undefined";
};

app.get(
  "/protected",
  jwt({
    secret: "shhhhhhared-secret",
    algorithms: ["HS256"],
    isRevoked: isRevokedCallback,
  }),
  function (req, res) {
    if (!req.auth.admin) return res.sendStatus(401);
    res.sendStatus(200);
  }
);

Handling expired tokens

You can handle expired tokens as follows:

  jwt({
    secret: "shhhhhhared-secret",
    algorithms: ["HS256"],
    onExpired: async (req, err) => {
      if (new Date() - err.inner.expiredAt < 5000) { return;}
      throw err;
    },,
  })

Error handling

The default behavior is to throw an error when the token is invalid, so you can add your custom logic to manage unauthorized access as follows:

app.use(function (err, req, res, next) {
  if (err.name === "UnauthorizedError") {
    res.status(401).send("invalid token...");
  } else {
    next(err);
  }
});

You might want to use this module to identify registered users while still providing access to unregistered users. You can do this by using the option credentialsRequired:

app.use(
  jwt({
    secret: "hello world !",
    algorithms: ["HS256"],
    credentialsRequired: false,
  })
);

Typescript

A Request type is provided from express-jwt, which extends express.Request with the auth property. It could be aliased, like how JWTRequest is below.

import { expressjwt, Request as JWTRequest } from "express-jwt";

app.get(
  "/protected",
  expressjwt({ secret: "shhhhhhared-secret", algorithms: ["HS256"] }),
  function (req: JWTRequest, res: express.Response) {
    if (!req.auth?.admin) return res.sendStatus(401);
    res.sendStatus(200);
  }
);

Migration from v6

  1. The middleware function is now available as a named import rather than a default one: import { expressjwt } from 'express-jwt'
  2. The decoded JWT payload is now available as req.auth rather than req.user
  3. The secret function had (req, header, payload, cb), now it can return a promise and receives (req, token). token has header and payload.
  4. The isRevoked function had (req, payload, cb), now it can return a promise and receives (req, token). token has header and payload.

Related Modules

Tests

$ npm install
$ npm test

Contributors

Check them out here

Issue Reporting

If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. The Responsible Disclosure Program details the procedure for disclosing security issues.

Author

Auth0

License

This project is licensed under the MIT license. See the LICENSE file for more info.