2025-10-31 15:09:03 +08:00
|
|
|
|
---
|
|
|
|
|
|
--- Generated by EmmyLua(https://github.com/EmmyLua)
|
|
|
|
|
|
--- Created by frankly.
|
|
|
|
|
|
--- DateTime: 2025/10/31 09:29
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
local jwt = require("resty.jwt")
|
2025-11-01 23:00:27 +08:00
|
|
|
|
local jsonschema = require("jsonschema")
|
2025-11-10 19:34:43 +08:00
|
|
|
|
local conf = require("config")
|
2025-10-31 15:09:03 +08:00
|
|
|
|
|
|
|
|
|
|
local _M = {}
|
|
|
|
|
|
|
2025-11-01 23:00:27 +08:00
|
|
|
|
local schema = {
|
|
|
|
|
|
type = 'object',
|
|
|
|
|
|
properties = {
|
|
|
|
|
|
Authorization = {type = 'string', minLength = 10, pattern = 'Bearer\\s+(.+)$'},
|
|
|
|
|
|
}, required = {"Authorization"}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-31 15:09:03 +08:00
|
|
|
|
--设置JWT的有效载荷
|
|
|
|
|
|
local obj = {
|
2025-11-15 16:07:07 +08:00
|
|
|
|
header = { typ = "JWT", alg = "HS256" },
|
2025-10-31 15:09:03 +08:00
|
|
|
|
payload = { -- 自定义数据
|
|
|
|
|
|
userid = "", -- 用户id
|
|
|
|
|
|
username = "", -- 用户名
|
2025-11-07 17:06:39 +08:00
|
|
|
|
role_id = "", -- 角色id
|
|
|
|
|
|
role_name = "", -- 角色名称
|
2025-10-31 15:09:03 +08:00
|
|
|
|
--iss = "your_issuer", -- 签发者
|
|
|
|
|
|
--sub = "1234567890", -- 主题
|
2025-11-07 17:06:39 +08:00
|
|
|
|
exp = ngx.time() + 3600, -- 过期时间(例如:当前时间+1小时)
|
|
|
|
|
|
iat = ngx.time() -- 签发时间
|
2025-10-31 15:09:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-10 19:34:43 +08:00
|
|
|
|
--通过参数生存jwt相关的token值
|
2025-11-07 17:06:39 +08:00
|
|
|
|
function _M.generateToken(userid, username, role_id, role_name)
|
|
|
|
|
|
if userid == nil or username == nil or role_id == nil or role_name == nil then
|
2025-10-31 15:09:03 +08:00
|
|
|
|
return ""
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
obj.payload.userid = userid
|
|
|
|
|
|
obj.payload.username = username
|
2025-11-07 17:06:39 +08:00
|
|
|
|
obj.payload.role_id = role_id
|
|
|
|
|
|
obj.payload.role_name = role_name
|
2025-10-31 15:09:03 +08:00
|
|
|
|
--获取的登陆的用户信息,返回tocken
|
2025-11-10 19:34:43 +08:00
|
|
|
|
local jwt_token = jwt:sign(conf.secret_key, obj)
|
2025-11-01 16:19:35 +08:00
|
|
|
|
return "Bearer "..jwt_token
|
2025-10-31 15:09:03 +08:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
--令牌校验
|
|
|
|
|
|
function _M.authorizationToken(auth_header)
|
|
|
|
|
|
--定义响应数据
|
|
|
|
|
|
local response = {}
|
|
|
|
|
|
--如果请求头中没有令牌,则直接返回401
|
|
|
|
|
|
if auth_header == nil or auth_header == "" then
|
|
|
|
|
|
response["code"] = 401
|
|
|
|
|
|
response["message"] = "没有找到令牌数据"
|
|
|
|
|
|
return response
|
|
|
|
|
|
end
|
2025-11-01 16:19:35 +08:00
|
|
|
|
|
2025-11-10 19:34:43 +08:00
|
|
|
|
--验证令牌是否符合要求
|
2025-11-01 23:00:27 +08:00
|
|
|
|
local validator = jsonschema.generate_validator(schema)
|
|
|
|
|
|
local data = {}
|
|
|
|
|
|
data.Authorization = auth_header
|
|
|
|
|
|
local ok = validator(data)
|
2025-10-31 15:09:03 +08:00
|
|
|
|
--如果没有Bearer,则表示令牌无效
|
2025-11-01 23:00:27 +08:00
|
|
|
|
if not ok then
|
2025-10-31 15:09:03 +08:00
|
|
|
|
response["code"] = 401
|
|
|
|
|
|
response["message"] = "令牌格式不正确"
|
|
|
|
|
|
return response
|
|
|
|
|
|
end
|
2025-11-01 16:19:35 +08:00
|
|
|
|
|
2025-11-01 23:00:27 +08:00
|
|
|
|
--查找令牌中的Bearer前缀字符,并进行截取
|
|
|
|
|
|
local token = string.sub(auth_header,8)
|
2025-10-31 15:09:03 +08:00
|
|
|
|
--校验令牌
|
2025-11-10 19:34:43 +08:00
|
|
|
|
local jwt_obj = jwt:verify(conf.secret_key, token)
|
2025-10-31 15:09:03 +08:00
|
|
|
|
--如果校验结果中的verified==false,则表示令牌无效
|
|
|
|
|
|
if jwt_obj.verified == false then
|
|
|
|
|
|
response["code"] = 401
|
|
|
|
|
|
response["message"] = "令牌无效"
|
|
|
|
|
|
return response
|
|
|
|
|
|
end
|
|
|
|
|
|
--判断token是否超时
|
2025-11-04 09:33:40 +08:00
|
|
|
|
if jwt_obj.payload.exp and ngx.time() > jwt_obj.payload.exp then
|
2025-10-31 15:45:00 +08:00
|
|
|
|
response["code"] = 401
|
|
|
|
|
|
response["message"] = "令牌已过期"
|
|
|
|
|
|
return response
|
|
|
|
|
|
end
|
2025-10-31 15:09:03 +08:00
|
|
|
|
--全部校验完成后,说明令牌有效,返回令牌数据
|
|
|
|
|
|
response["code"] = 200
|
|
|
|
|
|
response["message"] = "令牌校验通过"
|
|
|
|
|
|
response["body"] = jwt_obj
|
|
|
|
|
|
return response
|
|
|
|
|
|
end
|
|
|
|
|
|
|
2025-11-13 23:26:06 +08:00
|
|
|
|
local access_token_ttl = 10 * 60 --十分钟
|
|
|
|
|
|
local refresh_token_ttl = 7 * 24 * 3600 --7天
|
|
|
|
|
|
local id_token_ttl = 60 * 60 --1小时
|
|
|
|
|
|
|
|
|
|
|
|
-- 生成 Access Token(简化为 JWT 格式)
|
|
|
|
|
|
function _M.generate_access_token(priv_key, sub, client_id, scope)
|
|
|
|
|
|
local now = ngx.time()
|
|
|
|
|
|
local payload = {
|
|
|
|
|
|
--iss = OP_DOMAIN,
|
|
|
|
|
|
sub = sub,
|
2025-11-15 16:07:07 +08:00
|
|
|
|
aud = client_id,
|
2025-11-13 23:26:06 +08:00
|
|
|
|
exp = now + access_token_ttl,
|
|
|
|
|
|
iat = now,
|
|
|
|
|
|
scope = scope, --"openid profile email"
|
|
|
|
|
|
jti = ngx.md5(now .. math.random() .. client_id) -- 唯一标识
|
|
|
|
|
|
}
|
|
|
|
|
|
local access_token = jwt:sign(priv_key, {
|
|
|
|
|
|
header = { typ = "JWT", alg = "HS256" },
|
|
|
|
|
|
payload = payload
|
|
|
|
|
|
})
|
|
|
|
|
|
return access_token
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-- 生成 refresh Token(简化为 JWT 格式)
|
|
|
|
|
|
function _M.generate_refresh_token(priv_key, sub, client_id, scope)
|
|
|
|
|
|
local now = ngx.time()
|
|
|
|
|
|
local payload = {
|
|
|
|
|
|
--iss = OP_DOMAIN,
|
|
|
|
|
|
sub = sub,
|
2025-11-15 16:07:07 +08:00
|
|
|
|
aud = client_id,
|
2025-11-13 23:26:06 +08:00
|
|
|
|
exp = now + refresh_token_ttl,
|
|
|
|
|
|
iat = now,
|
|
|
|
|
|
scope = scope, --"openid profile email"
|
|
|
|
|
|
jti = ngx.md5(now .. math.random() * 1000 .. client_id)
|
|
|
|
|
|
}
|
|
|
|
|
|
local refresh_token = jwt:sign(priv_key, {
|
|
|
|
|
|
header = { typ = "JWT", alg = "HS256" },
|
|
|
|
|
|
payload = payload
|
|
|
|
|
|
})
|
|
|
|
|
|
return refresh_token
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-- 生成 ID Token(JWT)
|
|
|
|
|
|
function _M.generate_id_token(priv_key, sub, client_id, userinfo, scope)
|
|
|
|
|
|
local now = ngx.time()
|
|
|
|
|
|
local payload = {
|
|
|
|
|
|
--iss = OP_DOMAIN, -- issuer:OP 域名
|
|
|
|
|
|
sub = sub, -- subject:用户唯一标识
|
|
|
|
|
|
aud = client_id, -- audience:客户端 ID
|
|
|
|
|
|
exp = now + id_token_ttl, -- 过期时间(1小时)
|
|
|
|
|
|
iat = now, -- 签发时间
|
|
|
|
|
|
nonce = ngx.var.nonce, -- 可选:防重放攻击
|
|
|
|
|
|
--name = userinfo.name,
|
|
|
|
|
|
--email = userinfo.email
|
|
|
|
|
|
}
|
|
|
|
|
|
local id_token = jwt:sign(priv_key, {
|
|
|
|
|
|
header = { typ = "JWT", alg = "HS256" }, -- 算法可选 HS256/RS256
|
|
|
|
|
|
payload = payload
|
|
|
|
|
|
})
|
|
|
|
|
|
return id_token
|
|
|
|
|
|
end
|
|
|
|
|
|
|
2025-10-31 15:09:03 +08:00
|
|
|
|
return _M
|