lua-resty-jwt
用于 OpenResty 的 JWT
$ opm get cdbattags/lua-resty-jwt
名称
lua-resty-jwt - 用于 ngx_lua 和 LuaJIT 的 JWT
[!构建状态](https://travis-ci.org/cdbattags/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.12
状态
该库正在积极开发中,但被认为已准备好用于生产环境。
描述
该库需要一个启用了 OpenSSL 的 nginx 构建,以及 ngx_lua 模块、LuaJIT 2.0、lua-resty-hmac 和 lua-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)
';
}
}
方法
要加载此库,
您需要在 ngx_lua 的 lua_package_path 指令中指定此库的路径。例如,
lua_package_path "/path/to/lua-resty-jwt/lib/?.lua;;";
。您可以使用
require
将库加载到一个本地 Lua 变量中
local jwt = require "resty.jwt"
签名
语法:
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
的值),并返回 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 [, ...]])
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"}
}
验证
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
可以引发错误,验证将被视为失败,并且引发的错误将被放入结果对象的 reason 字段中。如果 validator
不返回任何内容(即 nil
),则该函数被视为已成功 - 假设如果失败,它会引发错误。
可以使用名为 __jwt
的特殊声明,以便如果存在该声明的 validator
函数,则该 validator
将使用整个已解析 jwt 对象的深度克隆作为 val
的值被调用。这样您就可以为可能依赖于一个或多个声明的整个对象编写验证。
可以向 jwt:load
和 jwt:verify_jwt_obj
指定多个 claim_spec
表格 - 并且它们将按顺序执行。单个 claim_spec
内的各个 validator
的执行顺序没有保证。如果 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_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
的值必须是非空表格,所有类型都相同。可选的 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_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
) 或正整数。
名称 ====
lua-resty-jwt - 用于 ngx_lua 和 LuaJIT 的 [JWT](http://self-issued.info/docs/draft-jones-json-web-token-01.html)
[](https://travis-ci.org/cdbattags/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/cdbattags/lua-resty-jwt/releases) 下载 `tar.gz` 文件
版本 =======
0.1.12
目录 =================
* [名称](#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` *可能*引发错误,并且验证将被视为失败,并且引发的错误将放入结果对象的 reason 字段中。如果 `validator` 没有返回任何内容(即 `nil`),则该函数被视为已成功 - 假设如果它失败,它会引发错误。
可以使用名为 `__jwt` 的特殊声明,以便如果为此声明存在 `validator` 函数,则将使用整个已解析 jwt 对象的深层克隆作为 `val` 的值调用 `validator`。这样您就可以为可能依赖于一个或多个声明的整个对象编写验证。
可以向 `jwt:load` 和 `jwt:verify_jwt_obj` 指定多个 `claim_spec` 表格 - 并且它们将按顺序执行。无法保证单个 `claim_spec` 内的各个 `validator` 的执行顺序。如果 `claim_spec` 失败,则任何后续的 `claim_spec` *将不会*执行。
### `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_
#### `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_spec`,您可以使用 `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 捆绑包](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 至少包含两个 nbf
或 exp
声明之一,并将当前时钟时间与这些边界进行比较。如果 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://travis-ci.org/cdbattags/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/cdbattags/lua-resty-jwt/releases) 下载 `tar.gz` 文件
版本 =======
0.1.12
目录 =================
* [名称](#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` *可能*引发错误,并且验证将被视为失败,并且引发的错误将放入结果对象的 reason 字段中。如果 `validator` 没有返回任何内容(即 `nil`),则该函数被视为已成功 - 假设如果它失败,它会引发错误。
可以使用名为 `__jwt` 的特殊声明,以便如果为此声明存在 `validator` 函数,则将使用整个已解析 jwt 对象的深层克隆作为 `val` 的值调用 `validator`。这样您就可以为可能依赖于一个或多个声明的整个对象编写验证。
可以向 `jwt:load` 和 `jwt:verify_jwt_obj` 指定多个 `claim_spec` 表格 - 并且它们将按顺序执行。无法保证单个 `claim_spec` 内的各个 `validator` 的执行顺序。如果 `claim_spec` 失败,则任何后续的 `claim_spec` *将不会*执行。
### `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_
#### `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_spec`,您可以使用 `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 捆绑包](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://travis-ci.org/cdbattags/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/cdbattags/lua-resty-jwt/releases) 下载 `tar.gz` 文件
版本 =======
0.1.12
目录 =================
* [名称](#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` *可能*引发错误,并且验证将被视为失败,并且引发的错误将放入结果对象的 reason 字段中。如果 `validator` 没有返回任何内容(即 `nil`),则该函数被视为已成功 - 假设如果它失败,它会引发错误。
可以使用名为 `__jwt` 的特殊声明,以便如果为此声明存在 `validator` 函数,则将使用整个已解析 jwt 对象的深层克隆作为 `val` 的值调用 `validator`。这样您就可以为可能依赖于一个或多个声明的整个对象编写验证。
可以向 `jwt:load` 和 `jwt:verify_jwt_obj` 指定多个 `claim_spec` 表格 - 并且它们将按顺序执行。无法保证单个 `claim_spec` 内的各个 `validator` 的执行顺序。如果 `claim_spec` 失败,则任何后续的 `claim_spec` *将不会*执行。
### `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_
#### `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_spec`,您可以使用 `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 捆绑包](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://travis-ci.org/cdbattags/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/cdbattags/lua-resty-jwt/releases) 下载 `tar.gz` 文件
版本 =======
0.1.12
目录 =================
* [名称](#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` *可能*引发错误,并且验证将被视为失败,并且引发的错误将放入结果对象的 reason 字段中。如果 `validator` 没有返回任何内容(即 `nil`),则该函数被视为已成功 - 假设如果它失败,它会引发错误。
可以使用名为 `__jwt` 的特殊声明,以便如果为此声明存在 `validator` 函数,则将使用整个已解析 jwt 对象的深层克隆作为 `val` 的值调用 `validator`。这样您就可以为可能依赖于一个或多个声明的整个对象编写验证。
可以向 `jwt:load` 和 `jwt:verify_jwt_obj` 指定多个 `claim_spec` 表格 - 并且它们将按顺序执行。无法保证单个 `claim_spec` 内的各个 `validator` 的执行顺序。如果 `claim_spec` 失败,则任何后续的 `claim_spec` *将不会*执行。
### `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_
#### `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_spec`,您可以使用 `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 捆绑包](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
作者
Christian Battaglia (cdbattags)
许可证
apache2
依赖项
jkeys089/lua-resty-hmac >= 0.02,luajit
版本
-
cdbattags/lua-resty-jwt 0.2.0适用于优秀的 Openresty 的 JWT 2018-06-06 18:15:14