lua-resty-jwt

适用于 OpenResty 的 JWT

$ opm get SkyLothar/lua-resty-jwt

名称

lua-resty-jwt - 用于 ngx_lua 和 LuaJIT 的 JWT

[!构建状态](https://travis-ci.org/SkyLothar/lua-resty-jwt)

注意 :exclamation: 这里使用的 hmac 库是 lua-resty-hmac,而不是 luarocks 中的。

安装

  • opm: opm get SkyLothar/lua-resty-jwt

  • luarocks: luarocks install lua-resty-jwt

  • 前往 发布页面 并下载 tar.gz

版本

0.1.10

状态

该库正在积极开发中,但被认为已准备好投入生产。

描述

此库需要使用 OpenSSL 构建的 nginx,ngx_lua 模块LuaJIT 2.0lua-resty-hmaclua-resty-string

概要

        # nginx.conf:
    
        lua_package_path "/path/to/lua-resty-jwt/lib/?.lua;;";
    
        server {
            default_type text/plain;
            location = /verify {
                content_by_lua '
                    local cjson = require "cjson"
                    local jwt = require "resty.jwt"
    
                    local jwt_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9" ..
                        ".eyJmb28iOiJiYXIifQ" ..
                        ".VAoRL1IU0nOguxURF2ZcKR0SGKE1gCbqwyh8u2MLAyY"
                    local jwt_obj = jwt:verify("lua-resty-jwt", jwt_token)
                    ngx.say(cjson.encode(jwt_obj))
                ';
            }
            location = /sign {
                content_by_lua '
                    local cjson = require "cjson"
                    local jwt = require "resty.jwt"
    
                    local jwt_token = jwt:sign(
                        "lua-resty-jwt",
                        {
                            header={typ="JWT", alg="HS256"},
                            payload={foo="bar"}
                        }
                    )
                    ngx.say(jwt_token)
                ';
            }
        }

方法

要加载此库,

  1. 您需要在 ngx_lua 的 lua_package_path 指令中指定此库的路径。例如,lua_package_path "/path/to/lua-resty-jwt/lib/?.lua;;";

  2. 您可以使用 require 将库加载到本地 Lua 变量中

        local jwt = require "resty.jwt"

签名

语法:local jwt_token = jwt:sign(key, table_of_jwt)

table_of_jwt 签名为 jwt_token

alg 参数指定要使用的哈希算法(HS256HS512RS256)。

table_of_jwt 示例

    {
        "header": {"typ": "JWT", "alg": "HS512"},
        "payload": {"foo": "bar"}
    }

验证

语法:local jwt_obj = jwt:verify(key, jwt_token [, claim_spec [, ...]])

验证 jwt_token 并返回一个 jwt_obj 表格。key 可以是预共享密钥(作为字符串),是一个函数,该函数接收单个参数(来自标头的 kid 的值),并返回预共享密钥(作为字符串)或如果 kid 查找失败则返回 nil。如果您尝试为 key 指定一个函数并且标头中不存在 kid,则此调用将失败。

有关 claim_spec 参数格式的详细信息,请参阅 验证

加载和验证

    syntax: local jwt_obj = jwt:load_jwt(jwt_token)
    syntax: local verified = jwt:verify_jwt_obj(key, jwt_obj [, claim_spec [, ...]])

验证 = 加载 JWT + 验证 JWT 对象

加载 JWT,检查 kid,然后使用正确的密钥进行验证

jwt_obj 示例

    {
        "raw_header": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9",
        "raw_payload: "eyJmb28iOiJiYXIifQ",
        "signature": "wrong-signature",
        "header": {"typ": "JWT", "alg": "HS256"},
        "payload": {"foo": "bar"},
        "verified": false,
        "valid": true,
        "reason": "signature mismatched: wrong-signature"
    }

签名 JWE

语法:local jwt_token = jwt:sign(key, table_of_jwt)

table_of_jwt 签名为 jwt_token

alg 参数指定用于加密密钥(dir)的哈希算法。enc 参数指定用于加密有效负载的哈希算法(A128CBC-HS256A256CBC-HS512

table_of_jwt 示例

    {
        "header": {"typ": "JWE", "alg": "dir", "enc":"A128CBC-HS256"},
        "payload": {"foo": "bar"}
    }

验证

jwt:loadjwt:verify_jwt_obj 函数都将任何数量的可选 claim_spec 参数作为附加参数。claim_spec 只是一个声明和验证器的 Lua 表格。claim_spec 表格中的每个键都对应于有效负载中的匹配键,并且 validator 是一个函数,将调用该函数以确定是否满足声明。

validator 函数的签名为

    function(val, claim, jwt_json)

其中 val 是正在测试的 jwt_obj 中声明的值(如果它不存在于对象的有放负载中则为 nil),claim 是正在验证的声明的名称,而 jwt_json 是正在验证的对象的 JSON 序列化表示形式。如果函数不需要 claimjwt_json 参数,则可以将其省略。

validator 函数返回 truefalse。任何 validator 可能引发错误,并且验证将被视为失败,并且引发的错误将放入结果对象的 reason 字段中。如果 validator 不返回任何内容(即 nil),则该函数将被视为已成功 - 在假设如果它失败则会引发错误的假设下。

可以使用名为 __jwt 的特殊声明,以便如果存在该声明的 validator 函数,则将使用整个已解析 JWT 对象的深拷贝作为 val 的值来调用该 validator。这样,您可以为可能依赖于一个或多个声明的整个对象编写验证。

可以向 jwt:loadjwt:verify_jwt_obj 指定多个 claim_spec 表格 - 并且它们将按顺序执行。无法保证单个 claim_spec 内的单个 validators 的执行顺序。如果 claim_spec 失败,则任何后续的 claim_specs 将不会执行。

claim_spec 示例

    {
        sub = function(val) return string.match("^[a-z]+$", val) end,
        iss = function(val)
            for _, value in pairs({ "first", "second" }) do
                if value == val then return true end
            end
            return false
        end,
        __jwt = function(val, claim, jwt_json)
            if val.payload.foo == nil or val.payload.bar == nil then
                error("Need to specify either 'foo' or 'bar'")
            end
        end
    }

JWT 验证器

resty.jwt-validators 中存在一个有用的 validator 函数库。您可以通过包含以下内容来使用此库:

    local validators = require "resty.jwt-validators"

验证器库中当前定义了以下函数。标记为“(opt)”表示存在名为 opt_<name> 的相同函数,该函数采用相同的参数。“opt”版本的函数如果键不存在于正在验证的 jwt_object 的有效负载中,则返回 true,而“非 opt”版本的函数如果键不存在于正在验证的 jwt_object 的有效负载中,则返回 false。

validators.chain(...) 返回一个验证器,该验证器将给定的函数一个接一个地链接在一起 - 只要它们继续通过其检查。

validators.required(chain_function) 返回一个验证器,如果值不存在,则返回 false。如果值存在并且指定了 chain_function,则将返回 chain_function(val, claim, jwt_json) 的值,否则将返回 true。这允许指定一个值既是必需的并且它必须匹配某些其他检查。

validators.require_one_of(claim_keys) 返回一个验证器,如果没有给定的声明键存在,则会显示错误消息。预计此函数用于完整的 jwt 对象。claim_keys 必须是非空字符串表。

validators.check(check_val, check_function, name, check_type) (opt) 返回一个验证器,该验证器检查对测试值和 check_val 调用给定 check_function 的结果是否返回 true。check_valcheck_function 的值不能为 nil。可选的 name 用于错误消息,默认为“check_value”。可选的 check_type 用于确保检查类型匹配,默认为 type(check_val)。传递给 check_function 的第一个参数永远不会为 nil。如果 check_function 引发错误,则该错误将附加到错误消息中。

validators.equals(check_val) (opt) 返回一个验证器,该验证器检查值是否完全等于(使用 ==)给定的 check_value。check_val 的值不能为 nil。

validators.matches(pattern) (opt) 返回一个验证器,该验证器检查值是否匹配给定的模式(使用 string.match)。pattern 的值必须是字符串。

validators.any_of(check_values, check_function, name, check_type, table_type) (opt) 返回一个验证器,该验证器对给定的 check_values 和测试值中的每一个调用给定的 check_function。如果这些调用中的任何一个返回 true,则此函数返回 truecheck_values 的值必须是非空表,所有类型都相同,并且 check_function 的值不能为 nil。可选的 name 用于错误消息,默认为“check_values”。可选的 check_type 用于确保检查类型匹配,默认为 type(check_values[1]) - 表格类型。

validators.equals_any_of(check_values) (opt) 返回一个验证器,该验证器检查值是否完全等于给定的 check_values 中的任何一个。

validators.matches_any_of(patterns) (opt) 返回一个验证器,该验证器检查值是否匹配给定的 patterns 中的任何一个。

validators.contains_any_of(check_values,name) (opt) 返回一个验证器,该验证器检查预期类型为 string 的值是否存在于给定的 check_values 中的任何一个中。check_values 的值必须是非空表,所有类型都相同。可选的 name 用于错误消息,默认为 check_values

validators.greater_than(check_val) (opt) 返回一个验证器,该验证器检查值如何(数值上,使用 >)与给定的 check_value 进行比较。check_val 的值不能为 nil,并且必须是数字。

validators.greater_than_or_equal(check_val) (opt) 返回一个验证器,该验证器检查值如何(数值上,使用 >=)与给定的 check_value 进行比较。check_val 的值不能为 nil,并且必须是数字。

validators.less_than(check_val) (opt) 返回一个验证器,该验证器检查值如何(数值上,使用 <)与给定的 check_value 进行比较。check_val 的值不能为 nil,并且必须是数字。

validators.less_than_or_equal(check_val) (opt) 返回一个验证器,该验证器检查值如何(数值上,使用 <=)与给定的 check_value 进行比较。check_val 的值不能为 nil,并且必须是数字。

validators.is_not_before() (opt) 返回一个验证器,该验证器检查当前时间是否不在系统容差内的测试值之前。这意味着

    val <= (system_clock() + system_leeway).

validators.is_not_expired() (opt) 返回一个验证器,该验证器检查当前时间是否不等于或晚于系统容差内的测试值。这意味着

    val > (system_clock() - system_leeway).

validators.is_at() (opt) 返回一个验证器,该验证器检查当前时间是否与系统容差内的测试值相同。这意味着

    val >= (system_clock() - system_leeway) and val <= (system_clock() + system_leeway).

validators.set_system_leeway(leeway) 用于设置 is_not_beforeis_not_expired 使用的容差(以秒为单位)的函数。默认为使用 0

validators.set_system_clock(clock) 用于设置 is_not_beforeis_not_expired 使用的系统时钟的函数。默认为使用 ngx.now

使用验证器的 claim_spec 示例

    local validators = require "resty.jwt-validators"
    local claim_spec = {
        sub = validators.opt_matches("^[a-z]+$),
        iss = validators.equals_any_of({ "first", "second" }),
        __jwt = validators.require_one_of({ "foo", "bar" })
    }

旧版/时间范围选项

为了支持使用此库的先前版本的代码,以及简化指定基于时间范围的 claim_specs,您可以使用 validation_options 表格代替任何单个 claim_spec 参数。参数应表示为键/值表。表中的每个键都应从以下列表中选择。

使用旧版 validation_options 时,您只能指定这些选项。也就是说,您不能将旧版 validation_options 与其他 claim_spec 验证器混合使用。为了实现这一点,您必须向 jwt:load/jwt:verify_jwt_obj 函数指定多个选项。

  • lifetime_grace_period:定义以秒为单位的容差,以考虑生成 jwt 的服务器与验证它的服务器之间的时钟偏差。值应为零 (0) 或正整数。

名称 ====

lua-resty-jwt - 用于 ngx_lua 和 LuaJIT 的 [JWT](http://self-issued.info/docs/draft-jones-json-web-token-01.html)

[![构建状态](https://img.shields.io/travis/SkyLothar/lua-resty-jwt.svg?style=flat-square)](https://travis-ci.org/SkyLothar/lua-resty-jwt)

**注意 :exclamation: 这里使用的 hmac 库是 [lua-resty-hmac](https://github.com/jkeys089/lua-resty-hmac),而不是 luarocks 中的。**

安装 ============ - opm: `opm get SkyLothar/lua-resty-jwt` - luarocks: `luarocks install lua-resty-jwt` - 前往 [发布页面](https://github.com/SkyLothar/lua-resty-jwt/releases) 并下载 `tar.gz`

版本 =======

0.1.10

目录 =================

* [名称](#name) * [状态](#status) * [描述](#description) * [概要](#synopsis) * [方法](#methods) * [签名](#sign) * [验证](#verify) * [加载和验证](#load--verify) * [签名 JWE](#sign-jwe) * [验证](#verification) * [JWT 验证器](#jwt-validators) * [旧版/时间范围选项](#legacy-timeframe-options) * [示例](#examples) * [安装](#installation) * [使用 Docker 进行测试](#testing-with-docker) * [作者](AUTHORS.md) * [另请参阅](#see-also)

状态 ======

该库正在积极开发中,但被认为已准备好投入生产。

描述 ===========

此库需要使用 OpenSSL 构建的 nginx,[ngx_lua 模块](http://wiki.nginx.org/HttpLuaModule),[LuaJIT 2.0](http://luajit.org/luajit.html),[lua-resty-hmac](https://github.com/jkeys089/lua-resty-hmac) 和 [lua-resty-string](https://github.com/openresty/lua-resty-string)。

概要 ========

```lua # nginx.conf

    lua_package_path "/path/to/lua-resty-jwt/lib/?.lua;;";

    server {
        default_type text/plain;
        location = /verify {
            content_by_lua '
                local cjson = require "cjson"
                local jwt = require "resty.jwt"

                local jwt_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9" ..
                    ".eyJmb28iOiJiYXIifQ" ..
                    ".VAoRL1IU0nOguxURF2ZcKR0SGKE1gCbqwyh8u2MLAyY"
                local jwt_obj = jwt:verify("lua-resty-jwt", jwt_token)
                ngx.say(cjson.encode(jwt_obj))
            ';
        }
        location = /sign {
            content_by_lua '
                local cjson = require "cjson"
                local jwt = require "resty.jwt"

                local jwt_token = jwt:sign(
                    "lua-resty-jwt",
                    {
                        header={typ="JWT", alg="HS256"},
                        payload={foo="bar"}
                    }
                )
                ngx.say(jwt_token)
            ';
        }
    }
```

[返回目录](#table-of-contents)

方法 =======

要加载此库,

1. 您需要在 ngx_lua 的 [lua_package_path](https://github.com/openresty/lua-nginx-module#lua_package_path) 指令中指定此库的路径。例如,`lua_package_path "/path/to/lua-resty-jwt/lib/?.lua;;";`。2. 使用 `require` 将库加载到本地 Lua 变量中

```lua local jwt = require "resty.jwt" ```

[返回目录](#table-of-contents)

签名 ----

`语法: local jwt_token = jwt:sign(key, table_of_jwt)`

table_of_jwt 签名为 jwt_token

`alg` 参数指定要使用的哈希算法(`HS256`、`HS512`、`RS256`)。

### table_of_jwt 示例 ### ``` { "header": {"typ": "JWT", "alg": "HS512"}, "payload": {"foo": "bar"} } ```

验证 ------ `语法: local jwt_obj = jwt:verify(key, jwt_token [, claim_spec [, ...]])`

验证 jwt_token 并返回一个 jwt_obj 表格。`key` 可以是预共享密钥(作为字符串),*或者*是一个函数,该函数接受一个参数(来自标头的 `kid` 的值),并返回预共享密钥(作为字符串)或 `nil`(如果 `kid` 查找失败)。如果尝试为 `key` 指定函数且标头中不存在 `kid`,则此调用将失败。

有关 `claim_spec` 参数格式的详细信息,请参阅 [验证](#verification)。

加载和验证 ------------- ``` 语法: local jwt_obj = jwt:load_jwt(jwt_token) 语法: local verified = jwt:verify_jwt_obj(key, jwt_obj [, claim_spec [, ...]]) ```

__verify = load_jwt + verify_jwt_obj__

加载 JWT,检查 kid,然后使用正确的密钥进行验证

### jwt_obj 示例 ### ``` { "raw_header": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9", "raw_payload: "eyJmb28iOiJiYXIifQ", "signature": "wrong-signature", "header": {"typ": "JWT", "alg": "HS256"}, "payload": {"foo": "bar"}, "verified": false, "valid": true, "reason": "signature mismatched: wrong-signature" } ```

签名-jwe --------

`语法: local jwt_token = jwt:sign(key, table_of_jwt)`

table_of_jwt 签名为 jwt_token

`alg` 参数指定要用于加密密钥(`dir`)的哈希算法。`enc` 参数指定要用于加密有效负载(`A128CBC-HS256`、`A256CBC-HS512`)的哈希算法。

### table_of_jwt 示例 ### ``` { "header": {"typ": "JWE", "alg": "dir", "enc":"A128CBC-HS256"}, "payload": {"foo": "bar"} } ```

[返回目录](#table-of-contents)

验证 ============

`jwt:load` 和 `jwt:verify_jwt_obj` 函数都将任意数量的可选 `claim_spec` 参数作为附加参数。`claim_spec` 只是一个声明和验证器的 Lua 表格。`claim_spec` 表格中的每个键都对应于有效负载中的匹配键,并且 `validator` 是一个将被调用的函数,以确定是否满足声明。

`validator` 函数的签名为

``` function(val, claim, jwt_json) ```

其中 `val` 是正在测试的 `jwt_obj` 中声明的值(如果该值不存在于对象的有效负载中,则为 `nil`),`claim` 是正在验证的声明的名称,`jwt_json` 是正在验证的对象的 JSON 序列化表示形式。如果函数不需要 `claim` 或 `jwt_json` 参数,则可以省略它们。

`validator` 函数返回 `true` 或 `false`。任何 `validator` *可以*引发错误,验证将被视为失败,并且引发的错误将放入结果对象的原因字段中。如果 `validator` 没有返回任何内容(即 `nil`),则该函数被视为已成功 - 假设如果它失败,它会引发错误。

可以使用名为 `__jwt` 的特殊声明,以便如果为此声明存在 `validator` 函数,则该 `validator` 将使用整个已解析 jwt 对象的深拷贝作为 `val` 的值被调用。这样您就可以编写依赖于一个或多个声明的整个对象的验证。

可以向 `jwt:load` 和 `jwt:verify_jwt_obj` 指定多个 `claim_spec` 表格 - 并且它们将按顺序执行。单个 `claim_spec` 内的各个 `validators` 的执行顺序没有保证。如果 `claim_spec` 失败,则任何后续的 `claim_specs` *将不会*执行。

### `claim_spec` 示例 ### ``` { sub = function(val) return string.match("^[a-z]+$", val) end, iss = function(val) for _, value in pairs({ "first", "second" }) do if value == val then return true end end return false end, __jwt = function(val, claim, jwt_json) if val.payload.foo == nil or val.payload.bar == nil then error("Need to specify either 'foo' or 'bar'") end end } ```

JWT 验证器 --------------

`resty.jwt-validators` 中存在一个有用的 `validator` 函数库。您可以通过包含以下内容来使用此库:``` local validators = require "resty.jwt-validators" ```

验证器库中当前定义了以下函数。标有“(opt)”的函数表示存在名为 `opt_` 的相同函数,该函数采用相同的参数。“opt”版本的函数如果键不存在于正在验证的 jwt_object 的有效负载中,则返回 `true`,而非“opt”版本的函数如果键不存在于正在验证的 jwt_object 的有效负载中,则返回 `false`。

#### `validators.chain(...)` #### 返回一个验证器,该验证器将给定的函数一个接一个地链接在一起 - 只要它们继续通过检查。

#### `validators.required(chain_function)` #### 返回一个验证器,如果值不存在,则返回 `false`。如果值存在并且指定了 `chain_function`,则返回 `chain_function(val, claim, jwt_json)` 的值,否则返回 `true`。这允许指定值既是必需的*并且*它必须匹配某些其他检查。

#### `validators.require_one_of(claim_keys)` #### 返回一个验证器,如果*没有*给定的声明键存在,则会显示错误消息。预期此函数用于完整的 jwt 对象。`claim_keys` 必须是非空字符串表。

#### `validators.check(check_val, check_function, name, check_type)` (opt) #### 返回一个验证器,该验证器检查为测试值和 `check_val` 调用给定 `check_function` 的结果是否返回 `true`。`check_val` 和 `check_function` 的值不能为 `nil`。可选的 `name` 用于错误消息,默认为“check_value”。可选的 `check_type` 用于确保检查类型匹配,默认为 `type(check_val)`。传递给 `check_function` 的第一个参数*永远不会*为 `nil`。如果 `check_function` 引发错误,则该错误将附加到错误消息中。

#### `validators.equals(check_val)` (opt) #### 返回一个验证器,该验证器检查值是否完全等于(使用 `==`)给定的 `check_value`。`check_val` 的值不能为 `nil`。

#### `validators.matches(pattern)` (opt) #### 返回一个验证器,该验证器检查值是否匹配给定的模式(使用 `string.match`)。`pattern` 的值必须是字符串。

#### `validators.any_of(check_values, check_function, name, check_type, table_type)` (opt) #### 返回一个验证器,该验证器为每个给定的 `check_values` 和测试值调用给定的 `check_function`。如果这些调用中的任何一个返回 `true`,则此函数返回 `true`。`check_values` 的值必须是非空表,并且所有类型都相同,`check_function` 的值不能为 `nil`。可选的 `name` 用于错误消息,默认为“check_values”。可选的 `check_type` 用于确保检查类型匹配,默认为 `type(check_values[1])` - 表格类型。

#### `validators.equals_any_of(check_values)` (opt) #### 返回一个验证器,该验证器检查值是否完全等于给定的 `check_values` 中的任何一个。

#### `validators.matches_any_of(patterns)` (opt) #### 返回一个验证器,该验证器检查值是否匹配给定的 `patterns` 中的任何一个。

#### `validators.contains_any_of(check_values,name)` (opt) #### 返回一个验证器,该验证器检查预期类型为 `string` 的值是否存在于给定的 `check_values` 中的任何一个。`check_values` 的值必须是非空表,并且所有类型都相同。可选的名称用于错误消息,默认为 `check_values`。

#### `validators.greater_than(check_val)` (opt) #### 返回一个验证器,该验证器检查值如何与(数值上,使用 `>`)给定的 `check_value` 进行比较。`check_val` 的值不能为 `nil`,并且必须是数字。

#### `validators.greater_than_or_equal(check_val)` (opt) #### 返回一个验证器,该验证器检查值如何与(数值上,使用 `>=`)给定的 `check_value` 进行比较。`check_val` 的值不能为 `nil`,并且必须是数字。

#### `validators.less_than(check_val)` (opt) #### 返回一个验证器,该验证器检查值如何与(数值上,使用 `<`)给定的 `check_value` 进行比较。`check_val` 的值不能为 `nil`,并且必须是数字。

#### `validators.less_than_or_equal(check_val)` (opt) #### 返回一个验证器,该验证器检查值如何与(数值上,使用 `<=`)给定的 `check_value` 进行比较。`check_val` 的值不能为 `nil`,并且必须是数字。

#### `validators.is_not_before()` (opt) #### 返回一个验证器,该验证器检查当前时间是否不在系统容差范围内之前测试值。这意味着:``` val <= (system_clock() + system_leeway). ```

#### `validators.is_not_expired()` (opt) #### 返回一个验证器,该验证器检查当前时间是否不等于或晚于系统容差范围内的测试值。这意味着:``` val > (system_clock() - system_leeway). ```

#### `validators.is_at()` (opt) #### 返回一个验证器,该验证器检查当前时间是否在系统容差范围内与测试值相同。这意味着:``` val >= (system_clock() - system_leeway) and val <= (system_clock() + system_leeway). ```

#### `validators.set_system_leeway(leeway)` #### 用于设置 `is_not_before` 和 `is_not_expired` 使用的容差(以秒为单位)的函数。默认情况下使用 `0` 秒

#### `validators.set_system_clock(clock)` #### 用于设置 `is_not_before` 和 `is_not_expired` 使用的系统时钟的函数。默认情况下使用 `ngx.now`

### 使用验证器的 `claim_spec` 示例 ### ``` local validators = require "resty.jwt-validators" local claim_spec = { sub = validators.opt_matches("^[a-z]+$), iss = validators.equals_any_of({ "first", "second" }), __jwt = validators.require_one_of({ "foo", "bar" }) } ```

旧版/时间范围选项 ------------------------

为了支持使用此库的先前版本的代码,以及简化指定基于时间范围的 `claim_specs`,您可以使用 `validation_options` 表格代替任何单个 `claim_spec` 参数。参数应表示为键/值表格。表格的每个键都应从以下列表中选择。

使用旧版 `validation_options` 时,您*只能*指定这些选项。也就是说,您不能将旧版 `validation_options` 与其他 `claim_spec` 验证器混合使用。为了实现这一点,您必须向 `jwt:load`/`jwt:verify_jwt_obj` 函数指定多个选项。

* `lifetime_grace_period`:定义以秒为单位的容差,以考虑生成 jwt 的服务器和验证它的服务器之间的时钟偏差。值应为零(`0`)或正整数。

    * When this validation option is specified, the process will ensure that the jwt contains at least one of the two `nbf` or `exp` claim and compare the current clock time against those boundaries. Would the jwt be deemed as expired or not valid yet, verification will fail.

    * When none of the `nbf` and `exp` claims can be found, verification will fail.

    * `nbf` and `exp` claims are expected to be expressed in the jwt as numerical values. Wouldn't that be the case, verification will fail.

    * Specifying this option is equivalent to calling:
      ```
      validators.set_system_leeway(leeway)
      ```

      and specifying as a `claim_spec`:
      ```
      {
        __jwt = validators.require_one_of({ "nbf", "exp" }),
        nbf = validators.opt_is_not_before(),
        exp = validators.opt_is_not_expired()
      }
      ```

* `require_nbf_claim`:表示 `nbf` 声明是可选的还是必需的。值应为布尔值。

    * When this validation option is set to `true` and no `lifetime_grace_period` has been specified, a zero (`0`) leeway is implied.

    * Specifying this option is equivalent to specifying as a `claim_spec`:
      ```
      {
        nbf = validators.is_not_before(),
      }
      ```

* `require_exp_claim`:表示 `exp` 声明是可选的还是必需的。值应为布尔值。

    * When this validation option is set to `true` and no `lifetime_grace_period` has been specified, a zero (`0`) leeway is implied.

    * Specifying this option is equivalent to specifying as a `claim_spec`:
      ```
      {
        exp = validators.is_not_expired(),
      }
      ```

* `valid_issuers`:将 jwt 的经过验证的发行者列入白名单。值应为字符串数组。

    * When this validation option is specified, the process will compare the jwt `iss` claim against the list of valid issuers. Comparison is done in a case sensitive manner. Would the jwt issuer not be found in the whitelist, verification will fail.

    * `iss` claim is expected to be expressed in the jwt as a string. Wouldn't that be the case, verification will fail.

    * Specifying this option is equivalent to specifying as a `claim_spec`:
      ```
      {
        iss = validators.equals_any_of(valid_issuers),
      }
      ```

### `validation_options` 用法示例 ### ``` local jwt_obj = jwt:verify(key, jwt_token, { lifetime_grace_period = 120, require_exp_claim = true, valid_issuers = { "my-trusted-issuer", "my-other-trusteed-issuer" } } ) ```

示例 ======== * [使用查询和 Cookie 的 JWT 身份验证](examples/README.md#jwt-auth-using-query-and-cookie) * [使用 KID 和在 Redis 中存储密钥的 JWT 身份验证](examples/README.md#jwt-auth-with-kid-and-store-keys-in-redis)

[返回目录](#table-of-contents)

安装 ============

使用 Luarocks ```bash luarocks install lua-resty-jwt ```

建议直接使用最新的 [ngx_openresty bundle](https://openresty.org.cn)。

此外,您需要配置 [lua_package_path](https://github.com/openresty/lua-nginx-module#lua_package_path) 指令,以将您的 lua-resty-jwt 源代码树的路径添加到 ngx_lua 的 Lua 模块搜索路径,如下所示

```nginx # nginx.conf http { lua_package_path "/path/to/lua-resty-jwt/lib/?.lua;;"; ... } ```

然后在 Lua 中加载库

```lua local jwt = require "resty.jwt" ```

[返回目录](#table-of-contents)

使用 Docker 进行测试 ===================

``` ./ci script ```

[返回目录](#table-of-contents)

另请参阅 ======== * ngx_lua 模块:http://wiki.nginx.org/HttpLuaModule

[返回目录](#table-of-contents) 当指定此验证选项时,流程将确保 jwt 包含 nbfexp 声明中的至少一个,并将当前时钟时间与这些边界进行比较。如果 jwt 被视为已过期或尚未有效,则验证将失败。

        When none of the C<nbf> and C<exp> claims can be found, verification will fail.

        C<nbf> and C<exp> claims are expected to be expressed in the jwt as numerical values. Wouldn't that be the case, verification will fail.

        Specifying this option is equivalent to calling:
C<>`
validators.set_system_leeway(leeway)
C<>`

      and specifying as a `claim_spec`:
      ```
      {
        __jwt = validators.require_one_of({ "nbf", "exp" }),
        nbf = validators.opt_is_not_before(),
        exp = validators.opt_is_not_expired()
      }
      ```
  • require_nbf_claim:表示 nbf 声明是否可选。值应为布尔值。

名称 ====

lua-resty-jwt - 用于 ngx_lua 和 LuaJIT 的 [JWT](http://self-issued.info/docs/draft-jones-json-web-token-01.html)

[![构建状态](https://img.shields.io/travis/SkyLothar/lua-resty-jwt.svg?style=flat-square)](https://travis-ci.org/SkyLothar/lua-resty-jwt)

**注意 :exclamation: 这里使用的 hmac 库是 [lua-resty-hmac](https://github.com/jkeys089/lua-resty-hmac),而不是 luarocks 中的。**

安装 ============ - opm: `opm get SkyLothar/lua-resty-jwt` - luarocks: `luarocks install lua-resty-jwt` - 前往 [发布页面](https://github.com/SkyLothar/lua-resty-jwt/releases) 并下载 `tar.gz`

版本 =======

0.1.10

目录 =================

* [名称](#name) * [状态](#status) * [描述](#description) * [概要](#synopsis) * [方法](#methods) * [签名](#sign) * [验证](#verify) * [加载和验证](#load--verify) * [签名 JWE](#sign-jwe) * [验证](#verification) * [JWT 验证器](#jwt-validators) * [旧版/时间范围选项](#legacy-timeframe-options) * [示例](#examples) * [安装](#installation) * [使用 Docker 进行测试](#testing-with-docker) * [作者](AUTHORS.md) * [另请参阅](#see-also)

状态 ======

该库正在积极开发中,但被认为已准备好投入生产。

描述 ===========

此库需要使用 OpenSSL 构建的 nginx,[ngx_lua 模块](http://wiki.nginx.org/HttpLuaModule),[LuaJIT 2.0](http://luajit.org/luajit.html),[lua-resty-hmac](https://github.com/jkeys089/lua-resty-hmac) 和 [lua-resty-string](https://github.com/openresty/lua-resty-string)。

概要 ========

```lua # nginx.conf

    lua_package_path "/path/to/lua-resty-jwt/lib/?.lua;;";

    server {
        default_type text/plain;
        location = /verify {
            content_by_lua '
                local cjson = require "cjson"
                local jwt = require "resty.jwt"

                local jwt_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9" ..
                    ".eyJmb28iOiJiYXIifQ" ..
                    ".VAoRL1IU0nOguxURF2ZcKR0SGKE1gCbqwyh8u2MLAyY"
                local jwt_obj = jwt:verify("lua-resty-jwt", jwt_token)
                ngx.say(cjson.encode(jwt_obj))
            ';
        }
        location = /sign {
            content_by_lua '
                local cjson = require "cjson"
                local jwt = require "resty.jwt"

                local jwt_token = jwt:sign(
                    "lua-resty-jwt",
                    {
                        header={typ="JWT", alg="HS256"},
                        payload={foo="bar"}
                    }
                )
                ngx.say(jwt_token)
            ';
        }
    }
```

[返回目录](#table-of-contents)

方法 =======

要加载此库,

1. 您需要在 ngx_lua 的 [lua_package_path](https://github.com/openresty/lua-nginx-module#lua_package_path) 指令中指定此库的路径。例如,`lua_package_path "/path/to/lua-resty-jwt/lib/?.lua;;";`。2. 使用 `require` 将库加载到本地 Lua 变量中

```lua local jwt = require "resty.jwt" ```

[返回目录](#table-of-contents)

签名 ----

`语法: local jwt_token = jwt:sign(key, table_of_jwt)`

table_of_jwt 签名为 jwt_token

`alg` 参数指定要使用的哈希算法(`HS256`、`HS512`、`RS256`)。

### table_of_jwt 示例 ### ``` { "header": {"typ": "JWT", "alg": "HS512"}, "payload": {"foo": "bar"} } ```

验证 ------ `语法: local jwt_obj = jwt:verify(key, jwt_token [, claim_spec [, ...]])`

验证 jwt_token 并返回一个 jwt_obj 表格。`key` 可以是预共享密钥(作为字符串),*或者*是一个函数,该函数接受一个参数(来自标头的 `kid` 的值),并返回预共享密钥(作为字符串)或 `nil`(如果 `kid` 查找失败)。如果尝试为 `key` 指定函数且标头中不存在 `kid`,则此调用将失败。

有关 `claim_spec` 参数格式的详细信息,请参阅 [验证](#verification)。

加载和验证 ------------- ``` 语法: local jwt_obj = jwt:load_jwt(jwt_token) 语法: local verified = jwt:verify_jwt_obj(key, jwt_obj [, claim_spec [, ...]]) ```

__verify = load_jwt + verify_jwt_obj__

加载 JWT,检查 kid,然后使用正确的密钥进行验证

### jwt_obj 示例 ### ``` { "raw_header": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9", "raw_payload: "eyJmb28iOiJiYXIifQ", "signature": "wrong-signature", "header": {"typ": "JWT", "alg": "HS256"}, "payload": {"foo": "bar"}, "verified": false, "valid": true, "reason": "signature mismatched: wrong-signature" } ```

签名-jwe --------

`语法: local jwt_token = jwt:sign(key, table_of_jwt)`

table_of_jwt 签名为 jwt_token

`alg` 参数指定要用于加密密钥(`dir`)的哈希算法。`enc` 参数指定要用于加密有效负载(`A128CBC-HS256`、`A256CBC-HS512`)的哈希算法。

### table_of_jwt 示例 ### ``` { "header": {"typ": "JWE", "alg": "dir", "enc":"A128CBC-HS256"}, "payload": {"foo": "bar"} } ```

[返回目录](#table-of-contents)

验证 ============

`jwt:load` 和 `jwt:verify_jwt_obj` 函数都将任意数量的可选 `claim_spec` 参数作为附加参数。`claim_spec` 只是一个声明和验证器的 Lua 表格。`claim_spec` 表格中的每个键都对应于有效负载中的匹配键,并且 `validator` 是一个将被调用的函数,以确定是否满足声明。

`validator` 函数的签名为

``` function(val, claim, jwt_json) ```

其中 `val` 是正在测试的 `jwt_obj` 中声明的值(如果该值不存在于对象的有效负载中,则为 `nil`),`claim` 是正在验证的声明的名称,`jwt_json` 是正在验证的对象的 JSON 序列化表示形式。如果函数不需要 `claim` 或 `jwt_json` 参数,则可以省略它们。

`validator` 函数返回 `true` 或 `false`。任何 `validator` *可以*引发错误,验证将被视为失败,并且引发的错误将放入结果对象的原因字段中。如果 `validator` 没有返回任何内容(即 `nil`),则该函数被视为已成功 - 假设如果它失败,它会引发错误。

可以使用名为 `__jwt` 的特殊声明,以便如果为此声明存在 `validator` 函数,则该 `validator` 将使用整个已解析 jwt 对象的深拷贝作为 `val` 的值被调用。这样您就可以编写依赖于一个或多个声明的整个对象的验证。

可以向 `jwt:load` 和 `jwt:verify_jwt_obj` 指定多个 `claim_spec` 表格 - 并且它们将按顺序执行。单个 `claim_spec` 内的各个 `validators` 的执行顺序没有保证。如果 `claim_spec` 失败,则任何后续的 `claim_specs` *将不会*执行。

### `claim_spec` 示例 ### ``` { sub = function(val) return string.match("^[a-z]+$", val) end, iss = function(val) for _, value in pairs({ "first", "second" }) do if value == val then return true end end return false end, __jwt = function(val, claim, jwt_json) if val.payload.foo == nil or val.payload.bar == nil then error("Need to specify either 'foo' or 'bar'") end end } ```

JWT 验证器 --------------

`resty.jwt-validators` 中存在一个有用的 `validator` 函数库。您可以通过包含以下内容来使用此库:``` local validators = require "resty.jwt-validators" ```

验证器库中当前定义了以下函数。标有“(opt)”的函数表示存在名为 `opt_` 的相同函数,该函数采用相同的参数。“opt”版本的函数如果键不存在于正在验证的 jwt_object 的有效负载中,则返回 `true`,而非“opt”版本的函数如果键不存在于正在验证的 jwt_object 的有效负载中,则返回 `false`。

#### `validators.chain(...)` #### 返回一个验证器,该验证器将给定的函数一个接一个地链接在一起 - 只要它们继续通过检查。

#### `validators.required(chain_function)` #### 返回一个验证器,如果值不存在,则返回 `false`。如果值存在并且指定了 `chain_function`,则返回 `chain_function(val, claim, jwt_json)` 的值,否则返回 `true`。这允许指定值既是必需的*并且*它必须匹配某些其他检查。

#### `validators.require_one_of(claim_keys)` #### 返回一个验证器,如果*没有*给定的声明键存在,则会显示错误消息。预期此函数用于完整的 jwt 对象。`claim_keys` 必须是非空字符串表。

#### `validators.check(check_val, check_function, name, check_type)` (opt) #### 返回一个验证器,该验证器检查为测试值和 `check_val` 调用给定 `check_function` 的结果是否返回 `true`。`check_val` 和 `check_function` 的值不能为 `nil`。可选的 `name` 用于错误消息,默认为“check_value”。可选的 `check_type` 用于确保检查类型匹配,默认为 `type(check_val)`。传递给 `check_function` 的第一个参数*永远不会*为 `nil`。如果 `check_function` 引发错误,则该错误将附加到错误消息中。

#### `validators.equals(check_val)` (opt) #### 返回一个验证器,该验证器检查值是否完全等于(使用 `==`)给定的 `check_value`。`check_val` 的值不能为 `nil`。

#### `validators.matches(pattern)` (opt) #### 返回一个验证器,该验证器检查值是否匹配给定的模式(使用 `string.match`)。`pattern` 的值必须是字符串。

#### `validators.any_of(check_values, check_function, name, check_type, table_type)` (opt) #### 返回一个验证器,该验证器为每个给定的 `check_values` 和测试值调用给定的 `check_function`。如果这些调用中的任何一个返回 `true`,则此函数返回 `true`。`check_values` 的值必须是非空表,并且所有类型都相同,`check_function` 的值不能为 `nil`。可选的 `name` 用于错误消息,默认为“check_values”。可选的 `check_type` 用于确保检查类型匹配,默认为 `type(check_values[1])` - 表格类型。

#### `validators.equals_any_of(check_values)` (opt) #### 返回一个验证器,该验证器检查值是否完全等于给定的 `check_values` 中的任何一个。

#### `validators.matches_any_of(patterns)` (opt) #### 返回一个验证器,该验证器检查值是否匹配给定的 `patterns` 中的任何一个。

#### `validators.contains_any_of(check_values,name)` (opt) #### 返回一个验证器,该验证器检查预期类型为 `string` 的值是否存在于给定的 `check_values` 中的任何一个。`check_values` 的值必须是非空表,并且所有类型都相同。可选的名称用于错误消息,默认为 `check_values`。

#### `validators.greater_than(check_val)` (opt) #### 返回一个验证器,该验证器检查值如何与(数值上,使用 `>`)给定的 `check_value` 进行比较。`check_val` 的值不能为 `nil`,并且必须是数字。

#### `validators.greater_than_or_equal(check_val)` (opt) #### 返回一个验证器,该验证器检查值如何与(数值上,使用 `>=`)给定的 `check_value` 进行比较。`check_val` 的值不能为 `nil`,并且必须是数字。

#### `validators.less_than(check_val)` (opt) #### 返回一个验证器,该验证器检查值如何与(数值上,使用 `<`)给定的 `check_value` 进行比较。`check_val` 的值不能为 `nil`,并且必须是数字。

#### `validators.less_than_or_equal(check_val)` (opt) #### 返回一个验证器,该验证器检查值如何与(数值上,使用 `<=`)给定的 `check_value` 进行比较。`check_val` 的值不能为 `nil`,并且必须是数字。

#### `validators.is_not_before()` (opt) #### 返回一个验证器,该验证器检查当前时间是否不在系统容差范围内之前测试值。这意味着:``` val <= (system_clock() + system_leeway). ```

#### `validators.is_not_expired()` (opt) #### 返回一个验证器,该验证器检查当前时间是否不等于或晚于系统容差范围内的测试值。这意味着:``` val > (system_clock() - system_leeway). ```

#### `validators.is_at()` (opt) #### 返回一个验证器,该验证器检查当前时间是否在系统容差范围内与测试值相同。这意味着:``` val >= (system_clock() - system_leeway) and val <= (system_clock() + system_leeway). ```

#### `validators.set_system_leeway(leeway)` #### 用于设置 `is_not_before` 和 `is_not_expired` 使用的容差(以秒为单位)的函数。默认情况下使用 `0` 秒

#### `validators.set_system_clock(clock)` #### 用于设置 `is_not_before` 和 `is_not_expired` 使用的系统时钟的函数。默认情况下使用 `ngx.now`

### 使用验证器的 `claim_spec` 示例 ### ``` local validators = require "resty.jwt-validators" local claim_spec = { sub = validators.opt_matches("^[a-z]+$), iss = validators.equals_any_of({ "first", "second" }), __jwt = validators.require_one_of({ "foo", "bar" }) } ```

旧版/时间范围选项 ------------------------

为了支持使用此库的先前版本的代码,以及简化指定基于时间范围的 `claim_specs`,您可以使用 `validation_options` 表格代替任何单个 `claim_spec` 参数。参数应表示为键/值表格。表格的每个键都应从以下列表中选择。

使用旧版 `validation_options` 时,您*只能*指定这些选项。也就是说,您不能将旧版 `validation_options` 与其他 `claim_spec` 验证器混合使用。为了实现这一点,您必须向 `jwt:load`/`jwt:verify_jwt_obj` 函数指定多个选项。

* `lifetime_grace_period`:定义以秒为单位的容差,以考虑生成 jwt 的服务器和验证它的服务器之间的时钟偏差。值应为零(`0`)或正整数。

    * When this validation option is specified, the process will ensure that the jwt contains at least one of the two `nbf` or `exp` claim and compare the current clock time against those boundaries. Would the jwt be deemed as expired or not valid yet, verification will fail.

    * When none of the `nbf` and `exp` claims can be found, verification will fail.

    * `nbf` and `exp` claims are expected to be expressed in the jwt as numerical values. Wouldn't that be the case, verification will fail.

    * Specifying this option is equivalent to calling:
      ```
      validators.set_system_leeway(leeway)
      ```

      and specifying as a `claim_spec`:
      ```
      {
        __jwt = validators.require_one_of({ "nbf", "exp" }),
        nbf = validators.opt_is_not_before(),
        exp = validators.opt_is_not_expired()
      }
      ```

* `require_nbf_claim`:表示 `nbf` 声明是可选的还是必需的。值应为布尔值。

    * When this validation option is set to `true` and no `lifetime_grace_period` has been specified, a zero (`0`) leeway is implied.

    * Specifying this option is equivalent to specifying as a `claim_spec`:
      ```
      {
        nbf = validators.is_not_before(),
      }
      ```

* `require_exp_claim`:表示 `exp` 声明是可选的还是必需的。值应为布尔值。

    * When this validation option is set to `true` and no `lifetime_grace_period` has been specified, a zero (`0`) leeway is implied.

    * Specifying this option is equivalent to specifying as a `claim_spec`:
      ```
      {
        exp = validators.is_not_expired(),
      }
      ```

* `valid_issuers`:将 jwt 的经过验证的发行者列入白名单。值应为字符串数组。

    * When this validation option is specified, the process will compare the jwt `iss` claim against the list of valid issuers. Comparison is done in a case sensitive manner. Would the jwt issuer not be found in the whitelist, verification will fail.

    * `iss` claim is expected to be expressed in the jwt as a string. Wouldn't that be the case, verification will fail.

    * Specifying this option is equivalent to specifying as a `claim_spec`:
      ```
      {
        iss = validators.equals_any_of(valid_issuers),
      }
      ```

### `validation_options` 用法示例 ### ``` local jwt_obj = jwt:verify(key, jwt_token, { lifetime_grace_period = 120, require_exp_claim = true, valid_issuers = { "my-trusted-issuer", "my-other-trusteed-issuer" } } ) ```

示例 ======== * [使用查询和 Cookie 的 JWT 身份验证](examples/README.md#jwt-auth-using-query-and-cookie) * [使用 KID 和在 Redis 中存储密钥的 JWT 身份验证](examples/README.md#jwt-auth-with-kid-and-store-keys-in-redis)

[返回目录](#table-of-contents)

安装 ============

使用 Luarocks ```bash luarocks install lua-resty-jwt ```

建议直接使用最新的 [ngx_openresty bundle](https://openresty.org.cn)。

此外,您需要配置 [lua_package_path](https://github.com/openresty/lua-nginx-module#lua_package_path) 指令,以将您的 lua-resty-jwt 源代码树的路径添加到 ngx_lua 的 Lua 模块搜索路径,如下所示

```nginx # nginx.conf http { lua_package_path "/path/to/lua-resty-jwt/lib/?.lua;;"; ... } ```

然后在 Lua 中加载库

```lua local jwt = require "resty.jwt" ```

[返回目录](#table-of-contents)

使用 Docker 进行测试 ===================

``` ./ci script ```

[返回目录](#table-of-contents)

另请参阅 ======== * ngx_lua 模块:http://wiki.nginx.org/HttpLuaModule

[返回目录](#table-of-contents) 当此验证选项设置为 true 且未指定 lifetime_grace_period 时,则隐含零 (0) 宽限期。

        Specifying this option is equivalent to specifying as a C<claim_spec>:
C<>`
{
nbf = validators.is_not_before(),
}
C<>`
  • require_exp_claim:表示 exp 声明是否可选。值应为布尔值。

名称 ====

lua-resty-jwt - 用于 ngx_lua 和 LuaJIT 的 [JWT](http://self-issued.info/docs/draft-jones-json-web-token-01.html)

[![构建状态](https://img.shields.io/travis/SkyLothar/lua-resty-jwt.svg?style=flat-square)](https://travis-ci.org/SkyLothar/lua-resty-jwt)

**注意 :exclamation: 这里使用的 hmac 库是 [lua-resty-hmac](https://github.com/jkeys089/lua-resty-hmac),而不是 luarocks 中的。**

安装 ============ - opm: `opm get SkyLothar/lua-resty-jwt` - luarocks: `luarocks install lua-resty-jwt` - 前往 [发布页面](https://github.com/SkyLothar/lua-resty-jwt/releases) 并下载 `tar.gz`

版本 =======

0.1.10

目录 =================

* [名称](#name) * [状态](#status) * [描述](#description) * [概要](#synopsis) * [方法](#methods) * [签名](#sign) * [验证](#verify) * [加载和验证](#load--verify) * [签名 JWE](#sign-jwe) * [验证](#verification) * [JWT 验证器](#jwt-validators) * [旧版/时间范围选项](#legacy-timeframe-options) * [示例](#examples) * [安装](#installation) * [使用 Docker 进行测试](#testing-with-docker) * [作者](AUTHORS.md) * [另请参阅](#see-also)

状态 ======

该库正在积极开发中,但被认为已准备好投入生产。

描述 ===========

此库需要使用 OpenSSL 构建的 nginx,[ngx_lua 模块](http://wiki.nginx.org/HttpLuaModule),[LuaJIT 2.0](http://luajit.org/luajit.html),[lua-resty-hmac](https://github.com/jkeys089/lua-resty-hmac) 和 [lua-resty-string](https://github.com/openresty/lua-resty-string)。

概要 ========

```lua # nginx.conf

    lua_package_path "/path/to/lua-resty-jwt/lib/?.lua;;";

    server {
        default_type text/plain;
        location = /verify {
            content_by_lua '
                local cjson = require "cjson"
                local jwt = require "resty.jwt"

                local jwt_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9" ..
                    ".eyJmb28iOiJiYXIifQ" ..
                    ".VAoRL1IU0nOguxURF2ZcKR0SGKE1gCbqwyh8u2MLAyY"
                local jwt_obj = jwt:verify("lua-resty-jwt", jwt_token)
                ngx.say(cjson.encode(jwt_obj))
            ';
        }
        location = /sign {
            content_by_lua '
                local cjson = require "cjson"
                local jwt = require "resty.jwt"

                local jwt_token = jwt:sign(
                    "lua-resty-jwt",
                    {
                        header={typ="JWT", alg="HS256"},
                        payload={foo="bar"}
                    }
                )
                ngx.say(jwt_token)
            ';
        }
    }
```

[返回目录](#table-of-contents)

方法 =======

要加载此库,

1. 您需要在 ngx_lua 的 [lua_package_path](https://github.com/openresty/lua-nginx-module#lua_package_path) 指令中指定此库的路径。例如,`lua_package_path "/path/to/lua-resty-jwt/lib/?.lua;;";`。2. 使用 `require` 将库加载到本地 Lua 变量中

```lua local jwt = require "resty.jwt" ```

[返回目录](#table-of-contents)

签名 ----

`语法: local jwt_token = jwt:sign(key, table_of_jwt)`

table_of_jwt 签名为 jwt_token

`alg` 参数指定要使用的哈希算法(`HS256`、`HS512`、`RS256`)。

### table_of_jwt 示例 ### ``` { "header": {"typ": "JWT", "alg": "HS512"}, "payload": {"foo": "bar"} } ```

验证 ------ `语法: local jwt_obj = jwt:verify(key, jwt_token [, claim_spec [, ...]])`

验证 jwt_token 并返回一个 jwt_obj 表格。`key` 可以是预共享密钥(作为字符串),*或者*是一个函数,该函数接受一个参数(来自标头的 `kid` 的值),并返回预共享密钥(作为字符串)或 `nil`(如果 `kid` 查找失败)。如果尝试为 `key` 指定函数且标头中不存在 `kid`,则此调用将失败。

有关 `claim_spec` 参数格式的详细信息,请参阅 [验证](#verification)。

加载和验证 ------------- ``` 语法: local jwt_obj = jwt:load_jwt(jwt_token) 语法: local verified = jwt:verify_jwt_obj(key, jwt_obj [, claim_spec [, ...]]) ```

__verify = load_jwt + verify_jwt_obj__

加载 JWT,检查 kid,然后使用正确的密钥进行验证

### jwt_obj 示例 ### ``` { "raw_header": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9", "raw_payload: "eyJmb28iOiJiYXIifQ", "signature": "wrong-signature", "header": {"typ": "JWT", "alg": "HS256"}, "payload": {"foo": "bar"}, "verified": false, "valid": true, "reason": "signature mismatched: wrong-signature" } ```

签名-jwe --------

`语法: local jwt_token = jwt:sign(key, table_of_jwt)`

table_of_jwt 签名为 jwt_token

`alg` 参数指定要用于加密密钥(`dir`)的哈希算法。`enc` 参数指定要用于加密有效负载(`A128CBC-HS256`、`A256CBC-HS512`)的哈希算法。

### table_of_jwt 示例 ### ``` { "header": {"typ": "JWE", "alg": "dir", "enc":"A128CBC-HS256"}, "payload": {"foo": "bar"} } ```

[返回目录](#table-of-contents)

验证 ============

`jwt:load` 和 `jwt:verify_jwt_obj` 函数都将任意数量的可选 `claim_spec` 参数作为附加参数。`claim_spec` 只是一个声明和验证器的 Lua 表格。`claim_spec` 表格中的每个键都对应于有效负载中的匹配键,并且 `validator` 是一个将被调用的函数,以确定是否满足声明。

`validator` 函数的签名为

``` function(val, claim, jwt_json) ```

其中 `val` 是正在测试的 `jwt_obj` 中声明的值(如果该值不存在于对象的有效负载中,则为 `nil`),`claim` 是正在验证的声明的名称,`jwt_json` 是正在验证的对象的 JSON 序列化表示形式。如果函数不需要 `claim` 或 `jwt_json` 参数,则可以省略它们。

`validator` 函数返回 `true` 或 `false`。任何 `validator` *可以*引发错误,验证将被视为失败,并且引发的错误将放入结果对象的原因字段中。如果 `validator` 没有返回任何内容(即 `nil`),则该函数被视为已成功 - 假设如果它失败,它会引发错误。

可以使用名为 `__jwt` 的特殊声明,以便如果为此声明存在 `validator` 函数,则该 `validator` 将使用整个已解析 jwt 对象的深拷贝作为 `val` 的值被调用。这样您就可以编写依赖于一个或多个声明的整个对象的验证。

可以向 `jwt:load` 和 `jwt:verify_jwt_obj` 指定多个 `claim_spec` 表格 - 并且它们将按顺序执行。单个 `claim_spec` 内的各个 `validators` 的执行顺序没有保证。如果 `claim_spec` 失败,则任何后续的 `claim_specs` *将不会*执行。

### `claim_spec` 示例 ### ``` { sub = function(val) return string.match("^[a-z]+$", val) end, iss = function(val) for _, value in pairs({ "first", "second" }) do if value == val then return true end end return false end, __jwt = function(val, claim, jwt_json) if val.payload.foo == nil or val.payload.bar == nil then error("Need to specify either 'foo' or 'bar'") end end } ```

JWT 验证器 --------------

`resty.jwt-validators` 中存在一个有用的 `validator` 函数库。您可以通过包含以下内容来使用此库:``` local validators = require "resty.jwt-validators" ```

验证器库中当前定义了以下函数。标有“(opt)”的函数表示存在名为 `opt_` 的相同函数,该函数采用相同的参数。“opt”版本的函数如果键不存在于正在验证的 jwt_object 的有效负载中,则返回 `true`,而非“opt”版本的函数如果键不存在于正在验证的 jwt_object 的有效负载中,则返回 `false`。

#### `validators.chain(...)` #### 返回一个验证器,该验证器将给定的函数一个接一个地链接在一起 - 只要它们继续通过检查。

#### `validators.required(chain_function)` #### 返回一个验证器,如果值不存在,则返回 `false`。如果值存在并且指定了 `chain_function`,则返回 `chain_function(val, claim, jwt_json)` 的值,否则返回 `true`。这允许指定值既是必需的*并且*它必须匹配某些其他检查。

#### `validators.require_one_of(claim_keys)` #### 返回一个验证器,如果*没有*给定的声明键存在,则会显示错误消息。预期此函数用于完整的 jwt 对象。`claim_keys` 必须是非空字符串表。

#### `validators.check(check_val, check_function, name, check_type)` (opt) #### 返回一个验证器,该验证器检查为测试值和 `check_val` 调用给定 `check_function` 的结果是否返回 `true`。`check_val` 和 `check_function` 的值不能为 `nil`。可选的 `name` 用于错误消息,默认为“check_value”。可选的 `check_type` 用于确保检查类型匹配,默认为 `type(check_val)`。传递给 `check_function` 的第一个参数*永远不会*为 `nil`。如果 `check_function` 引发错误,则该错误将附加到错误消息中。

#### `validators.equals(check_val)` (opt) #### 返回一个验证器,该验证器检查值是否完全等于(使用 `==`)给定的 `check_value`。`check_val` 的值不能为 `nil`。

#### `validators.matches(pattern)` (opt) #### 返回一个验证器,该验证器检查值是否匹配给定的模式(使用 `string.match`)。`pattern` 的值必须是字符串。

#### `validators.any_of(check_values, check_function, name, check_type, table_type)` (opt) #### 返回一个验证器,该验证器为每个给定的 `check_values` 和测试值调用给定的 `check_function`。如果这些调用中的任何一个返回 `true`,则此函数返回 `true`。`check_values` 的值必须是非空表,并且所有类型都相同,`check_function` 的值不能为 `nil`。可选的 `name` 用于错误消息,默认为“check_values”。可选的 `check_type` 用于确保检查类型匹配,默认为 `type(check_values[1])` - 表格类型。

#### `validators.equals_any_of(check_values)` (opt) #### 返回一个验证器,该验证器检查值是否完全等于给定的 `check_values` 中的任何一个。

#### `validators.matches_any_of(patterns)` (opt) #### 返回一个验证器,该验证器检查值是否匹配给定的 `patterns` 中的任何一个。

#### `validators.contains_any_of(check_values,name)` (opt) #### 返回一个验证器,该验证器检查预期类型为 `string` 的值是否存在于给定的 `check_values` 中的任何一个。`check_values` 的值必须是非空表,并且所有类型都相同。可选的名称用于错误消息,默认为 `check_values`。

#### `validators.greater_than(check_val)` (opt) #### 返回一个验证器,该验证器检查值如何与(数值上,使用 `>`)给定的 `check_value` 进行比较。`check_val` 的值不能为 `nil`,并且必须是数字。

#### `validators.greater_than_or_equal(check_val)` (opt) #### 返回一个验证器,该验证器检查值如何与(数值上,使用 `>=`)给定的 `check_value` 进行比较。`check_val` 的值不能为 `nil`,并且必须是数字。

#### `validators.less_than(check_val)` (opt) #### 返回一个验证器,该验证器检查值如何与(数值上,使用 `<`)给定的 `check_value` 进行比较。`check_val` 的值不能为 `nil`,并且必须是数字。

#### `validators.less_than_or_equal(check_val)` (opt) #### 返回一个验证器,该验证器检查值如何与(数值上,使用 `<=`)给定的 `check_value` 进行比较。`check_val` 的值不能为 `nil`,并且必须是数字。

#### `validators.is_not_before()` (opt) #### 返回一个验证器,该验证器检查当前时间是否不在系统容差范围内之前测试值。这意味着:``` val <= (system_clock() + system_leeway). ```

#### `validators.is_not_expired()` (opt) #### 返回一个验证器,该验证器检查当前时间是否不等于或晚于系统容差范围内的测试值。这意味着:``` val > (system_clock() - system_leeway). ```

#### `validators.is_at()` (opt) #### 返回一个验证器,该验证器检查当前时间是否在系统容差范围内与测试值相同。这意味着:``` val >= (system_clock() - system_leeway) and val <= (system_clock() + system_leeway). ```

#### `validators.set_system_leeway(leeway)` #### 用于设置 `is_not_before` 和 `is_not_expired` 使用的容差(以秒为单位)的函数。默认情况下使用 `0` 秒

#### `validators.set_system_clock(clock)` #### 用于设置 `is_not_before` 和 `is_not_expired` 使用的系统时钟的函数。默认情况下使用 `ngx.now`

### 使用验证器的 `claim_spec` 示例 ### ``` local validators = require "resty.jwt-validators" local claim_spec = { sub = validators.opt_matches("^[a-z]+$), iss = validators.equals_any_of({ "first", "second" }), __jwt = validators.require_one_of({ "foo", "bar" }) } ```

旧版/时间范围选项 ------------------------

为了支持使用此库的先前版本的代码,以及简化指定基于时间范围的 `claim_specs`,您可以使用 `validation_options` 表格代替任何单个 `claim_spec` 参数。参数应表示为键/值表格。表格的每个键都应从以下列表中选择。

使用旧版 `validation_options` 时,您*只能*指定这些选项。也就是说,您不能将旧版 `validation_options` 与其他 `claim_spec` 验证器混合使用。为了实现这一点,您必须向 `jwt:load`/`jwt:verify_jwt_obj` 函数指定多个选项。

* `lifetime_grace_period`:定义以秒为单位的容差,以考虑生成 jwt 的服务器和验证它的服务器之间的时钟偏差。值应为零(`0`)或正整数。

    * When this validation option is specified, the process will ensure that the jwt contains at least one of the two `nbf` or `exp` claim and compare the current clock time against those boundaries. Would the jwt be deemed as expired or not valid yet, verification will fail.

    * When none of the `nbf` and `exp` claims can be found, verification will fail.

    * `nbf` and `exp` claims are expected to be expressed in the jwt as numerical values. Wouldn't that be the case, verification will fail.

    * Specifying this option is equivalent to calling:
      ```
      validators.set_system_leeway(leeway)
      ```

      and specifying as a `claim_spec`:
      ```
      {
        __jwt = validators.require_one_of({ "nbf", "exp" }),
        nbf = validators.opt_is_not_before(),
        exp = validators.opt_is_not_expired()
      }
      ```

* `require_nbf_claim`:表示 `nbf` 声明是可选的还是必需的。值应为布尔值。

    * When this validation option is set to `true` and no `lifetime_grace_period` has been specified, a zero (`0`) leeway is implied.

    * Specifying this option is equivalent to specifying as a `claim_spec`:
      ```
      {
        nbf = validators.is_not_before(),
      }
      ```

* `require_exp_claim`:表示 `exp` 声明是可选的还是必需的。值应为布尔值。

    * When this validation option is set to `true` and no `lifetime_grace_period` has been specified, a zero (`0`) leeway is implied.

    * Specifying this option is equivalent to specifying as a `claim_spec`:
      ```
      {
        exp = validators.is_not_expired(),
      }
      ```

* `valid_issuers`:将 jwt 的经过验证的发行者列入白名单。值应为字符串数组。

    * When this validation option is specified, the process will compare the jwt `iss` claim against the list of valid issuers. Comparison is done in a case sensitive manner. Would the jwt issuer not be found in the whitelist, verification will fail.

    * `iss` claim is expected to be expressed in the jwt as a string. Wouldn't that be the case, verification will fail.

    * Specifying this option is equivalent to specifying as a `claim_spec`:
      ```
      {
        iss = validators.equals_any_of(valid_issuers),
      }
      ```

### `validation_options` 用法示例 ### ``` local jwt_obj = jwt:verify(key, jwt_token, { lifetime_grace_period = 120, require_exp_claim = true, valid_issuers = { "my-trusted-issuer", "my-other-trusteed-issuer" } } ) ```

示例 ======== * [使用查询和 Cookie 的 JWT 身份验证](examples/README.md#jwt-auth-using-query-and-cookie) * [使用 KID 和在 Redis 中存储密钥的 JWT 身份验证](examples/README.md#jwt-auth-with-kid-and-store-keys-in-redis)

[返回目录](#table-of-contents)

安装 ============

使用 Luarocks ```bash luarocks install lua-resty-jwt ```

建议直接使用最新的 [ngx_openresty bundle](https://openresty.org.cn)。

此外,您需要配置 [lua_package_path](https://github.com/openresty/lua-nginx-module#lua_package_path) 指令,以将您的 lua-resty-jwt 源代码树的路径添加到 ngx_lua 的 Lua 模块搜索路径,如下所示

```nginx # nginx.conf http { lua_package_path "/path/to/lua-resty-jwt/lib/?.lua;;"; ... } ```

然后在 Lua 中加载库

```lua local jwt = require "resty.jwt" ```

[返回目录](#table-of-contents)

使用 Docker 进行测试 ===================

``` ./ci script ```

[返回目录](#table-of-contents)

另请参阅 ======== * ngx_lua 模块:http://wiki.nginx.org/HttpLuaModule

[返回目录](#table-of-contents) 当此验证选项设置为 true 且未指定 lifetime_grace_period 时,则隐含零 (0) 宽限期。

        Specifying this option is equivalent to specifying as a C<claim_spec>:
C<>`
{
exp = validators.is_not_expired(),
}
C<>`
  • valid_issuers:将 jwt 的已验证发行者列入白名单。值应为字符串数组。

名称 ====

lua-resty-jwt - 用于 ngx_lua 和 LuaJIT 的 [JWT](http://self-issued.info/docs/draft-jones-json-web-token-01.html)

[![构建状态](https://img.shields.io/travis/SkyLothar/lua-resty-jwt.svg?style=flat-square)](https://travis-ci.org/SkyLothar/lua-resty-jwt)

**注意 :exclamation: 这里使用的 hmac 库是 [lua-resty-hmac](https://github.com/jkeys089/lua-resty-hmac),而不是 luarocks 中的。**

安装 ============ - opm: `opm get SkyLothar/lua-resty-jwt` - luarocks: `luarocks install lua-resty-jwt` - 前往 [发布页面](https://github.com/SkyLothar/lua-resty-jwt/releases) 并下载 `tar.gz`

版本 =======

0.1.10

目录 =================

* [名称](#name) * [状态](#status) * [描述](#description) * [概要](#synopsis) * [方法](#methods) * [签名](#sign) * [验证](#verify) * [加载和验证](#load--verify) * [签名 JWE](#sign-jwe) * [验证](#verification) * [JWT 验证器](#jwt-validators) * [旧版/时间范围选项](#legacy-timeframe-options) * [示例](#examples) * [安装](#installation) * [使用 Docker 进行测试](#testing-with-docker) * [作者](AUTHORS.md) * [另请参阅](#see-also)

状态 ======

该库正在积极开发中,但被认为已准备好投入生产。

描述 ===========

此库需要使用 OpenSSL 构建的 nginx,[ngx_lua 模块](http://wiki.nginx.org/HttpLuaModule),[LuaJIT 2.0](http://luajit.org/luajit.html),[lua-resty-hmac](https://github.com/jkeys089/lua-resty-hmac) 和 [lua-resty-string](https://github.com/openresty/lua-resty-string)。

概要 ========

```lua # nginx.conf

    lua_package_path "/path/to/lua-resty-jwt/lib/?.lua;;";

    server {
        default_type text/plain;
        location = /verify {
            content_by_lua '
                local cjson = require "cjson"
                local jwt = require "resty.jwt"

                local jwt_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9" ..
                    ".eyJmb28iOiJiYXIifQ" ..
                    ".VAoRL1IU0nOguxURF2ZcKR0SGKE1gCbqwyh8u2MLAyY"
                local jwt_obj = jwt:verify("lua-resty-jwt", jwt_token)
                ngx.say(cjson.encode(jwt_obj))
            ';
        }
        location = /sign {
            content_by_lua '
                local cjson = require "cjson"
                local jwt = require "resty.jwt"

                local jwt_token = jwt:sign(
                    "lua-resty-jwt",
                    {
                        header={typ="JWT", alg="HS256"},
                        payload={foo="bar"}
                    }
                )
                ngx.say(jwt_token)
            ';
        }
    }
```

[返回目录](#table-of-contents)

方法 =======

要加载此库,

1. 您需要在 ngx_lua 的 [lua_package_path](https://github.com/openresty/lua-nginx-module#lua_package_path) 指令中指定此库的路径。例如,`lua_package_path "/path/to/lua-resty-jwt/lib/?.lua;;";`。2. 使用 `require` 将库加载到本地 Lua 变量中

```lua local jwt = require "resty.jwt" ```

[返回目录](#table-of-contents)

签名 ----

`语法: local jwt_token = jwt:sign(key, table_of_jwt)`

table_of_jwt 签名为 jwt_token

`alg` 参数指定要使用的哈希算法(`HS256`、`HS512`、`RS256`)。

### table_of_jwt 示例 ### ``` { "header": {"typ": "JWT", "alg": "HS512"}, "payload": {"foo": "bar"} } ```

验证 ------ `语法: local jwt_obj = jwt:verify(key, jwt_token [, claim_spec [, ...]])`

验证 jwt_token 并返回一个 jwt_obj 表格。`key` 可以是预共享密钥(作为字符串),*或者*是一个函数,该函数接受一个参数(来自标头的 `kid` 的值),并返回预共享密钥(作为字符串)或 `nil`(如果 `kid` 查找失败)。如果尝试为 `key` 指定函数且标头中不存在 `kid`,则此调用将失败。

有关 `claim_spec` 参数格式的详细信息,请参阅 [验证](#verification)。

加载和验证 ------------- ``` 语法: local jwt_obj = jwt:load_jwt(jwt_token) 语法: local verified = jwt:verify_jwt_obj(key, jwt_obj [, claim_spec [, ...]]) ```

__verify = load_jwt + verify_jwt_obj__

加载 JWT,检查 kid,然后使用正确的密钥进行验证

### jwt_obj 示例 ### ``` { "raw_header": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9", "raw_payload: "eyJmb28iOiJiYXIifQ", "signature": "wrong-signature", "header": {"typ": "JWT", "alg": "HS256"}, "payload": {"foo": "bar"}, "verified": false, "valid": true, "reason": "signature mismatched: wrong-signature" } ```

签名-jwe --------

`语法: local jwt_token = jwt:sign(key, table_of_jwt)`

table_of_jwt 签名为 jwt_token

`alg` 参数指定要用于加密密钥(`dir`)的哈希算法。`enc` 参数指定要用于加密有效负载(`A128CBC-HS256`、`A256CBC-HS512`)的哈希算法。

### table_of_jwt 示例 ### ``` { "header": {"typ": "JWE", "alg": "dir", "enc":"A128CBC-HS256"}, "payload": {"foo": "bar"} } ```

[返回目录](#table-of-contents)

验证 ============

`jwt:load` 和 `jwt:verify_jwt_obj` 函数都将任意数量的可选 `claim_spec` 参数作为附加参数。`claim_spec` 只是一个声明和验证器的 Lua 表格。`claim_spec` 表格中的每个键都对应于有效负载中的匹配键,并且 `validator` 是一个将被调用的函数,以确定是否满足声明。

`validator` 函数的签名为

``` function(val, claim, jwt_json) ```

其中 `val` 是正在测试的 `jwt_obj` 中声明的值(如果该值不存在于对象的有效负载中,则为 `nil`),`claim` 是正在验证的声明的名称,`jwt_json` 是正在验证的对象的 JSON 序列化表示形式。如果函数不需要 `claim` 或 `jwt_json` 参数,则可以省略它们。

`validator` 函数返回 `true` 或 `false`。任何 `validator` *可以*引发错误,验证将被视为失败,并且引发的错误将放入结果对象的原因字段中。如果 `validator` 没有返回任何内容(即 `nil`),则该函数被视为已成功 - 假设如果它失败,它会引发错误。

可以使用名为 `__jwt` 的特殊声明,以便如果为此声明存在 `validator` 函数,则该 `validator` 将使用整个已解析 jwt 对象的深拷贝作为 `val` 的值被调用。这样您就可以编写依赖于一个或多个声明的整个对象的验证。

可以向 `jwt:load` 和 `jwt:verify_jwt_obj` 指定多个 `claim_spec` 表格 - 并且它们将按顺序执行。单个 `claim_spec` 内的各个 `validators` 的执行顺序没有保证。如果 `claim_spec` 失败,则任何后续的 `claim_specs` *将不会*执行。

### `claim_spec` 示例 ### ``` { sub = function(val) return string.match("^[a-z]+$", val) end, iss = function(val) for _, value in pairs({ "first", "second" }) do if value == val then return true end end return false end, __jwt = function(val, claim, jwt_json) if val.payload.foo == nil or val.payload.bar == nil then error("Need to specify either 'foo' or 'bar'") end end } ```

JWT 验证器 --------------

`resty.jwt-validators` 中存在一个有用的 `validator` 函数库。您可以通过包含以下内容来使用此库:``` local validators = require "resty.jwt-validators" ```

验证器库中当前定义了以下函数。标有“(opt)”的函数表示存在名为 `opt_` 的相同函数,该函数采用相同的参数。“opt”版本的函数如果键不存在于正在验证的 jwt_object 的有效负载中,则返回 `true`,而非“opt”版本的函数如果键不存在于正在验证的 jwt_object 的有效负载中,则返回 `false`。

#### `validators.chain(...)` #### 返回一个验证器,该验证器将给定的函数一个接一个地链接在一起 - 只要它们继续通过检查。

#### `validators.required(chain_function)` #### 返回一个验证器,如果值不存在,则返回 `false`。如果值存在并且指定了 `chain_function`,则返回 `chain_function(val, claim, jwt_json)` 的值,否则返回 `true`。这允许指定值既是必需的*并且*它必须匹配某些其他检查。

#### `validators.require_one_of(claim_keys)` #### 返回一个验证器,如果*没有*给定的声明键存在,则会显示错误消息。预期此函数用于完整的 jwt 对象。`claim_keys` 必须是非空字符串表。

#### `validators.check(check_val, check_function, name, check_type)` (opt) #### 返回一个验证器,该验证器检查为测试值和 `check_val` 调用给定 `check_function` 的结果是否返回 `true`。`check_val` 和 `check_function` 的值不能为 `nil`。可选的 `name` 用于错误消息,默认为“check_value”。可选的 `check_type` 用于确保检查类型匹配,默认为 `type(check_val)`。传递给 `check_function` 的第一个参数*永远不会*为 `nil`。如果 `check_function` 引发错误,则该错误将附加到错误消息中。

#### `validators.equals(check_val)` (opt) #### 返回一个验证器,该验证器检查值是否完全等于(使用 `==`)给定的 `check_value`。`check_val` 的值不能为 `nil`。

#### `validators.matches(pattern)` (opt) #### 返回一个验证器,该验证器检查值是否匹配给定的模式(使用 `string.match`)。`pattern` 的值必须是字符串。

#### `validators.any_of(check_values, check_function, name, check_type, table_type)` (opt) #### 返回一个验证器,该验证器为每个给定的 `check_values` 和测试值调用给定的 `check_function`。如果这些调用中的任何一个返回 `true`,则此函数返回 `true`。`check_values` 的值必须是非空表,并且所有类型都相同,`check_function` 的值不能为 `nil`。可选的 `name` 用于错误消息,默认为“check_values”。可选的 `check_type` 用于确保检查类型匹配,默认为 `type(check_values[1])` - 表格类型。

#### `validators.equals_any_of(check_values)` (opt) #### 返回一个验证器,该验证器检查值是否完全等于给定的 `check_values` 中的任何一个。

#### `validators.matches_any_of(patterns)` (opt) #### 返回一个验证器,该验证器检查值是否匹配给定的 `patterns` 中的任何一个。

#### `validators.contains_any_of(check_values,name)` (opt) #### 返回一个验证器,该验证器检查预期类型为 `string` 的值是否存在于给定的 `check_values` 中的任何一个。`check_values` 的值必须是非空表,并且所有类型都相同。可选的名称用于错误消息,默认为 `check_values`。

#### `validators.greater_than(check_val)` (opt) #### 返回一个验证器,该验证器检查值如何与(数值上,使用 `>`)给定的 `check_value` 进行比较。`check_val` 的值不能为 `nil`,并且必须是数字。

#### `validators.greater_than_or_equal(check_val)` (opt) #### 返回一个验证器,该验证器检查值如何与(数值上,使用 `>=`)给定的 `check_value` 进行比较。`check_val` 的值不能为 `nil`,并且必须是数字。

#### `validators.less_than(check_val)` (opt) #### 返回一个验证器,该验证器检查值如何与(数值上,使用 `<`)给定的 `check_value` 进行比较。`check_val` 的值不能为 `nil`,并且必须是数字。

#### `validators.less_than_or_equal(check_val)` (opt) #### 返回一个验证器,该验证器检查值如何与(数值上,使用 `<=`)给定的 `check_value` 进行比较。`check_val` 的值不能为 `nil`,并且必须是数字。

#### `validators.is_not_before()` (opt) #### 返回一个验证器,该验证器检查当前时间是否不在系统容差范围内之前测试值。这意味着:``` val <= (system_clock() + system_leeway). ```

#### `validators.is_not_expired()` (opt) #### 返回一个验证器,该验证器检查当前时间是否不等于或晚于系统容差范围内的测试值。这意味着:``` val > (system_clock() - system_leeway). ```

#### `validators.is_at()` (opt) #### 返回一个验证器,该验证器检查当前时间是否在系统容差范围内与测试值相同。这意味着:``` val >= (system_clock() - system_leeway) and val <= (system_clock() + system_leeway). ```

#### `validators.set_system_leeway(leeway)` #### 用于设置 `is_not_before` 和 `is_not_expired` 使用的容差(以秒为单位)的函数。默认情况下使用 `0` 秒

#### `validators.set_system_clock(clock)` #### 用于设置 `is_not_before` 和 `is_not_expired` 使用的系统时钟的函数。默认情况下使用 `ngx.now`

### 使用验证器的 `claim_spec` 示例 ### ``` local validators = require "resty.jwt-validators" local claim_spec = { sub = validators.opt_matches("^[a-z]+$), iss = validators.equals_any_of({ "first", "second" }), __jwt = validators.require_one_of({ "foo", "bar" }) } ```

旧版/时间范围选项 ------------------------

为了支持使用此库的先前版本的代码,以及简化指定基于时间范围的 `claim_specs`,您可以使用 `validation_options` 表格代替任何单个 `claim_spec` 参数。参数应表示为键/值表格。表格的每个键都应从以下列表中选择。

使用旧版 `validation_options` 时,您*只能*指定这些选项。也就是说,您不能将旧版 `validation_options` 与其他 `claim_spec` 验证器混合使用。为了实现这一点,您必须向 `jwt:load`/`jwt:verify_jwt_obj` 函数指定多个选项。

* `lifetime_grace_period`:定义以秒为单位的容差,以考虑生成 jwt 的服务器和验证它的服务器之间的时钟偏差。值应为零(`0`)或正整数。

    * When this validation option is specified, the process will ensure that the jwt contains at least one of the two `nbf` or `exp` claim and compare the current clock time against those boundaries. Would the jwt be deemed as expired or not valid yet, verification will fail.

    * When none of the `nbf` and `exp` claims can be found, verification will fail.

    * `nbf` and `exp` claims are expected to be expressed in the jwt as numerical values. Wouldn't that be the case, verification will fail.

    * Specifying this option is equivalent to calling:
      ```
      validators.set_system_leeway(leeway)
      ```

      and specifying as a `claim_spec`:
      ```
      {
        __jwt = validators.require_one_of({ "nbf", "exp" }),
        nbf = validators.opt_is_not_before(),
        exp = validators.opt_is_not_expired()
      }
      ```

* `require_nbf_claim`:表示 `nbf` 声明是可选的还是必需的。值应为布尔值。

    * When this validation option is set to `true` and no `lifetime_grace_period` has been specified, a zero (`0`) leeway is implied.

    * Specifying this option is equivalent to specifying as a `claim_spec`:
      ```
      {
        nbf = validators.is_not_before(),
      }
      ```

* `require_exp_claim`:表示 `exp` 声明是可选的还是必需的。值应为布尔值。

    * When this validation option is set to `true` and no `lifetime_grace_period` has been specified, a zero (`0`) leeway is implied.

    * Specifying this option is equivalent to specifying as a `claim_spec`:
      ```
      {
        exp = validators.is_not_expired(),
      }
      ```

* `valid_issuers`:将 jwt 的经过验证的发行者列入白名单。值应为字符串数组。

    * When this validation option is specified, the process will compare the jwt `iss` claim against the list of valid issuers. Comparison is done in a case sensitive manner. Would the jwt issuer not be found in the whitelist, verification will fail.

    * `iss` claim is expected to be expressed in the jwt as a string. Wouldn't that be the case, verification will fail.

    * Specifying this option is equivalent to specifying as a `claim_spec`:
      ```
      {
        iss = validators.equals_any_of(valid_issuers),
      }
      ```

### `validation_options` 用法示例 ### ``` local jwt_obj = jwt:verify(key, jwt_token, { lifetime_grace_period = 120, require_exp_claim = true, valid_issuers = { "my-trusted-issuer", "my-other-trusteed-issuer" } } ) ```

示例 ======== * [使用查询和 Cookie 的 JWT 身份验证](examples/README.md#jwt-auth-using-query-and-cookie) * [使用 KID 和在 Redis 中存储密钥的 JWT 身份验证](examples/README.md#jwt-auth-with-kid-and-store-keys-in-redis)

[返回目录](#table-of-contents)

安装 ============

使用 Luarocks ```bash luarocks install lua-resty-jwt ```

建议直接使用最新的 [ngx_openresty bundle](https://openresty.org.cn)。

此外,您需要配置 [lua_package_path](https://github.com/openresty/lua-nginx-module#lua_package_path) 指令,以将您的 lua-resty-jwt 源代码树的路径添加到 ngx_lua 的 Lua 模块搜索路径,如下所示

```nginx # nginx.conf http { lua_package_path "/path/to/lua-resty-jwt/lib/?.lua;;"; ... } ```

然后在 Lua 中加载库

```lua local jwt = require "resty.jwt" ```

[返回目录](#table-of-contents)

使用 Docker 进行测试 ===================

``` ./ci script ```

[返回目录](#table-of-contents)

另请参阅 ======== * ngx_lua 模块:http://wiki.nginx.org/HttpLuaModule

[返回目录](#table-of-contents) 当指定此验证选项时,流程将比较 jwt 的 iss 声明与有效发行者列表。比较以区分大小写的方式进行。如果 jwt 发行者未在白名单中找到,则验证将失败。

        C<iss> claim is expected to be expressed in the jwt as a string. Wouldn't that be the case, verification will fail.

        Specifying this option is equivalent to specifying as a C<claim_spec>:
C<>`
{
iss = validators.equals_any_of(valid_issuers),
}
C<>`

validation_options 用法示例

    local jwt_obj = jwt:verify(key, jwt_token,
        {
            lifetime_grace_period = 120,
            require_exp_claim = true,
            valid_issuers = { "my-trusted-issuer", "my-other-trusteed-issuer" }
        }
    )

示例

安装

使用 Luarocks

    luarocks install lua-resty-jwt

建议直接使用最新的 ngx_openresty 捆绑包

此外,您需要配置 lua_package_path 指令,将您的 lua-resty-jwt 源代码树的路径添加到 ngx_lua 的 Lua 模块搜索路径,如下所示

        # nginx.conf
        http {
            lua_package_path "/path/to/lua-resty-jwt/lib/?.lua;;";
            ...
        }

然后在 Lua 中加载库

        local jwt = require "resty.jwt"

使用 Docker 进行测试

    ./ci script

另请参阅

  • ngx_lua 模块:http://wiki.nginx.org/HttpLuaModule

作者

SkyLothar (skylothar)

许可证

apache2

依赖项

jkeys089/lua-resty-hmac >= 0.01, luajit

版本