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.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
查找失败则返回 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-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
函数,则将使用整个已解析 JWT 对象的深拷贝作为 val
的值来调用该 validator
。这样,您可以为可能依赖于一个或多个声明的整个对象编写验证。
可以向 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_<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://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_
#### `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 包含 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://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_
#### `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_
#### `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_
#### `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
版本
-
SkyLothar/lua-resty-jwt 0.1.11适用于优秀 Openresty 的 JWT 2017-07-11 18:10:15
-
SkyLothar/lua-resty-jwt 0.1.10适用于优秀 Openresty 的 JWT 2017-04-09 13:20:26
-
SkyLothar/lua-resty-jwt 0.1.9适用于优秀 Openresty 的 JWT 2016-11-25 16:58:24