@abramltd/jwt-oauth2-middleware 中文文档教程

发布于 6年前 浏览 21 项目主页 更新于 3年前

JWT OAUTH Middleware

该项目定义了一些中间件,用于使用 oauth2-node 创建 OAuth 服务器。 使用 express 作为预期服务器给出了一个示例。 目前仅支持 password 和 refresh_token 授权。

Usage & routes

简短使用版本(express.js 服务器示例):

    var oauth = require('insert-package-name')(model, config); // creating server middleware
    ... // express needed stuff

    app.post('/oauth/token', oauth.token); // (1) and (2)

    app.get('/validate', oauth.authenticate, function (req, res) { // (3)
        res.json({ message: 'Secure data' });
    });

任何实现 password 和 refresh_token 授权类型的 OAuth 服务器都需要三个路由:

  • one for generating access tokens (1)
  • one for generating new access tokens from unexpired refresh tokens (2)
  • one for token validation/gathering sensitive information (3)

Generating access tokens

通常,为用户获取访问令牌的路由是 <强>/令牌。 请求需要是 HTTP/HTTPS POST 并且所需数据在请求正文中发送。

Required dataValue
usernameuser's account username
client_idId of the client (application) that is requesting the user's access token
passworduser's account password
grant_typepassword
client_secretclient's secret used to sign token data
scopethe scope the generated access token needs to have

返回值示例如下所示。

    {
        "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRJZCI6IjEyMzUiLCJ1c2VySWQiOiI1OGVkMDUwYTczNGQxZDBlNjVmYzc3OTQiLCJ0eXBlIjoiYWNjZXNzVG9rZW4iLCJ1c2VybmFtZSI6IkRhbmEiLCJiYW5hbmEiOiJiYW5hbmEgd2hvIiwic2NvcGUiOiJiYW5hbmEiLCJleHBpcmVEYXRlIjoxNDk4MzI4MjY3NDc2LCJpYXQiOjE0OTgzMjgyMDcsImV4cCI6MTQ5ODMyODI2N30.KygbmACDVPYGoDpUg7YiyI5oAzQ5aUv8uqG0m9BDNg4",
        "token_type": "Bearer",
        "expires_in": 59, // seconds 
        "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRJZCI6IjEyMzUiLCJ1c2VySWQiOiI1OGVkMDUwYTczNGQxZDBlNjVmYzc3OTQiLCJ0eXBlIjoicmVmcmVzaFRva2VuIiwidXNlcm5hbWUiOiJEYW5hIiwiYmFuYW5hIjoiYmFuYW5hIHdobyIsInNjb3BlIjoiYmFuYW5hIiwiZXhwaXJlRGF0ZSI6MTQ5ODMyODI2NzQ3OCwiaWF0IjoxNDk4MzI4MjA3LCJleHAiOjE0OTgzMjgyNjd9.milncP0uopHUEU56ZqG1i9IDKDkP5ANfPQPFazMZLTE",
        "scope": "banana"
    }

Generating new access tokens from unexpired refresh tokens

通常,用户获取access token的路径是/token。 请求需要是 HTTP/HTTPS POST 并且所需数据在请求正文中发送。

Required dataValue
client_idId of the client (application) that is requesting the refresh of the user's access token
grant_typerefresh_token
client_secretclient's secret used to sign data, secret of the refresh token
refresh_tokenrefresh token used to retrieve the new access and refresh token. Musn't be expired

备注:如果token没有过期,它会被撤销,并且会颁发一对新的accessToken/refreshToken。 此外,新生成的令牌将与之前生成的令牌具有相同的范围。 一个例子如下所示。

    {
        "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRJZCI6IjEyMzUiLCJ1c2VySWQiOiI1OGVkMDUwYTczNGQxZDBlNjVmYzc3OTQiLCJ0eXBlIjoiYWNjZXNzVG9rZW4iLCJ1c2VybmFtZSI6IkRhbmEiLCJiYW5hbmEiOiJiYW5hbmEgd2hvIiwic2NvcGUiOiJiYW5hbmEiLCJleHBpcmVEYXRlIjoxNDk4MzI5MTY3OTkxLCJpYXQiOjE0OTgzMjkxMDcsImV4cCI6MTQ5ODMyOTE2N30._vbYF3f1DIcuiG_nX-8clYX6IgckIqY9n75NoLzw3tE",
        "token_type": "Bearer",
        "expires_in": 59, // seconds
        "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRJZCI6IjEyMzUiLCJ1c2VySWQiOiI1OGVkMDUwYTczNGQxZDBlNjVmYzc3OTQiLCJ0eXBlIjoicmVmcmVzaFRva2VuIiwidXNlcm5hbWUiOiJEYW5hIiwiYmFuYW5hIjoiYmFuYW5hIHdobyIsInNjb3BlIjoiYmFuYW5hIiwiZXhwaXJlRGF0ZSI6MTQ5ODMyOTE2Nzk5MywiaWF0IjoxNDk4MzI5MTA3LCJleHAiOjE0OTgzMjkxNjd9.GQU0bCFlu_qCuQgZtdTXTie6SPA08xVIv5Zv93ELFig",
        "scope": "banana"
    }

Token validation/gathering sensitive information

为了验证令牌或收集敏感信息,必须在所需路由上发出 HTTP GET 请求。 如果应验证范围,则请求应具有在 URL 查询中指定的范围。 查询参数的名称是scope

Model

为了创建中间件对象,必须提供模型对象和配置。 然而,并不是所有的模型功能都需要提供——只提供了部分功能。 下表显示了哪些 grant_types 需要哪些方法,以及是否在 (1)、(2) 或 (3) 中使用了该方法。

Model function nameDeclarationDescriptionGrant typesNeeded for (1)?Needed for (2)?Needed for (3)?
generateTokenData(client, user, scope) => data directly saved into the tokenSame for access token and refresh tokenBothyesyesno
getClientById(id) => Client : {id: string, refreshTokenSecret: string, accessTokenSecret: string}Returns client objectBothyesyesyes
getUserData(username, password) => either (User : {id: string}) or falseReturns user objectpasswordyesyesno
revokeRefreshToken(data) => booleanRevokes the supplied refresh token and returns whether the operation was successfulrefresh_tokennoyesno
saveToken(token, user, client) => Token with user and client data attached as follows {user: {id: string}, client: {id: string}}Saves both refresh and access tokensBothyesyesno
validateScopeUser(user, client, scope)=> either scope or falseUsed to see whether the user/client combination should/can have certain scopepasswordyesnono
verifyScopeAccessToken(data, scope) => booleanUsed to see whether the supplied access token can be used for the supplied scopeAuthenticate methodnonoyes

revokeRefreshToken 数据类型

  data = { 
      user: {id: string},
      client: {id: string},
      token: {
                    refreshToken: string, // token
                    expires: Date,
                    client: Client,
                    scope: string
      },
      scope: string
    };

verifyScopeAccessToken 数据类型

  data = {
            user: { id: string},
            token: {
                accessToken: string, //bearerToken,
                expires: Date,
                client: Client,
                scope: string
            },
            scope: string
 };

## Config

Config 需要为访问和刷新令牌定义以秒为单位的过期时间。 下面提供了示例。

  var config = {
    accessTokenExpiry: 60,             // seconds
    refreshTokenExpiry: 60,          // seconds
  };

JWT OAUTH Middleware

This project defines some middleware for the creation of OAuth Server using oauth2-node. An example is given using express as the intended server. Currently only password and refresh_token grants are supported.

Usage & routes

Short usage version (example with express.js server):

    var oauth = require('insert-package-name')(model, config); // creating server middleware
    ... // express needed stuff

    app.post('/oauth/token', oauth.token); // (1) and (2)

    app.get('/validate', oauth.authenticate, function (req, res) { // (3)
        res.json({ message: 'Secure data' });
    });

Any OAuth server that implements password and refresh_token grant types, needs to have three routes:

  • one for generating access tokens (1)
  • one for generating new access tokens from unexpired refresh tokens (2)
  • one for token validation/gathering sensitive information (3)

Generating access tokens

Usually, the route for acquiring an access token for a user is /token. The request needs to be HTTP/HTTPS POST and required data is sent in the request's body.

Required dataValue
usernameuser's account username
client_idId of the client (application) that is requesting the user's access token
passworduser's account password
grant_typepassword
client_secretclient's secret used to sign token data
scopethe scope the generated access token needs to have

The return value example is shown below.

    {
        "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRJZCI6IjEyMzUiLCJ1c2VySWQiOiI1OGVkMDUwYTczNGQxZDBlNjVmYzc3OTQiLCJ0eXBlIjoiYWNjZXNzVG9rZW4iLCJ1c2VybmFtZSI6IkRhbmEiLCJiYW5hbmEiOiJiYW5hbmEgd2hvIiwic2NvcGUiOiJiYW5hbmEiLCJleHBpcmVEYXRlIjoxNDk4MzI4MjY3NDc2LCJpYXQiOjE0OTgzMjgyMDcsImV4cCI6MTQ5ODMyODI2N30.KygbmACDVPYGoDpUg7YiyI5oAzQ5aUv8uqG0m9BDNg4",
        "token_type": "Bearer",
        "expires_in": 59, // seconds 
        "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRJZCI6IjEyMzUiLCJ1c2VySWQiOiI1OGVkMDUwYTczNGQxZDBlNjVmYzc3OTQiLCJ0eXBlIjoicmVmcmVzaFRva2VuIiwidXNlcm5hbWUiOiJEYW5hIiwiYmFuYW5hIjoiYmFuYW5hIHdobyIsInNjb3BlIjoiYmFuYW5hIiwiZXhwaXJlRGF0ZSI6MTQ5ODMyODI2NzQ3OCwiaWF0IjoxNDk4MzI4MjA3LCJleHAiOjE0OTgzMjgyNjd9.milncP0uopHUEU56ZqG1i9IDKDkP5ANfPQPFazMZLTE",
        "scope": "banana"
    }

Generating new access tokens from unexpired refresh tokens

Usually, the route for acquiring an access token for a user is /token. The request needs to be HTTP/HTTPS POST and required data is sent in the request's body.

Required dataValue
client_idId of the client (application) that is requesting the refresh of the user's access token
grant_typerefresh_token
client_secretclient's secret used to sign data, secret of the refresh token
refresh_tokenrefresh token used to retrieve the new access and refresh token. Musn't be expired

Remark: if the token isn't expired, it will be revoked and a new pair accessToken/refreshToken will be issued. In addition, the new generated tokens will have the same scope as the previously generated ones. An example is shown below.

    {
        "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRJZCI6IjEyMzUiLCJ1c2VySWQiOiI1OGVkMDUwYTczNGQxZDBlNjVmYzc3OTQiLCJ0eXBlIjoiYWNjZXNzVG9rZW4iLCJ1c2VybmFtZSI6IkRhbmEiLCJiYW5hbmEiOiJiYW5hbmEgd2hvIiwic2NvcGUiOiJiYW5hbmEiLCJleHBpcmVEYXRlIjoxNDk4MzI5MTY3OTkxLCJpYXQiOjE0OTgzMjkxMDcsImV4cCI6MTQ5ODMyOTE2N30._vbYF3f1DIcuiG_nX-8clYX6IgckIqY9n75NoLzw3tE",
        "token_type": "Bearer",
        "expires_in": 59, // seconds
        "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRJZCI6IjEyMzUiLCJ1c2VySWQiOiI1OGVkMDUwYTczNGQxZDBlNjVmYzc3OTQiLCJ0eXBlIjoicmVmcmVzaFRva2VuIiwidXNlcm5hbWUiOiJEYW5hIiwiYmFuYW5hIjoiYmFuYW5hIHdobyIsInNjb3BlIjoiYmFuYW5hIiwiZXhwaXJlRGF0ZSI6MTQ5ODMyOTE2Nzk5MywiaWF0IjoxNDk4MzI5MTA3LCJleHAiOjE0OTgzMjkxNjd9.GQU0bCFlu_qCuQgZtdTXTie6SPA08xVIv5Zv93ELFig",
        "scope": "banana"
    }

Token validation/gathering sensitive information

For validating the token or gathering sensitive information one must issue a HTTP GET request on a desired route. If scope should be validated, the request should have scope specified in the URL query. Query parameter's name is scope.

Model

In order to create the middleware object one must supply the model object and configuration. However, not all model functions need to be provided - partial functionality is provided. The following table shows which grant_types require which methods as well as show if the method is used in (1), (2) or (3).

Model function nameDeclarationDescriptionGrant typesNeeded for (1)?Needed for (2)?Needed for (3)?
generateTokenData(client, user, scope) => data directly saved into the tokenSame for access token and refresh tokenBothyesyesno
getClientById(id) => Client : {id: string, refreshTokenSecret: string, accessTokenSecret: string}Returns client objectBothyesyesyes
getUserData(username, password) => either (User : {id: string}) or falseReturns user objectpasswordyesyesno
revokeRefreshToken(data) => booleanRevokes the supplied refresh token and returns whether the operation was successfulrefresh_tokennoyesno
saveToken(token, user, client) => Token with user and client data attached as follows {user: {id: string}, client: {id: string}}Saves both refresh and access tokensBothyesyesno
validateScopeUser(user, client, scope)=> either scope or falseUsed to see whether the user/client combination should/can have certain scopepasswordyesnono
verifyScopeAccessToken(data, scope) => booleanUsed to see whether the supplied access token can be used for the supplied scopeAuthenticate methodnonoyes

revokeRefreshToken data type

  data = { 
      user: {id: string},
      client: {id: string},
      token: {
                    refreshToken: string, // token
                    expires: Date,
                    client: Client,
                    scope: string
      },
      scope: string
    };

verifyScopeAccessToken data type

  data = {
            user: { id: string},
            token: {
                accessToken: string, //bearerToken,
                expires: Date,
                client: Client,
                scope: string
            },
            scope: string
 };

## Config

Config needs to define expiration in seconds for both access and refresh token. Example is provided below.

  var config = {
    accessTokenExpiry: 60,             // seconds
    refreshTokenExpiry: 60,          // seconds
  };
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文