--- --- Generated by EmmyLua(https://github.com/EmmyLua) --- Created by frankly. --- DateTime: 2025/10/31 09:29 --- local jwt = require("resty.jwt") local jsonschema = require("jsonschema") local conf = require("config") local _M = {} local schema = { type = 'object', properties = { Authorization = {type = 'string', minLength = 10, pattern = 'Bearer\\s+(.+)$'}, }, required = {"Authorization"} } --设置JWT的有效载荷 local obj = { header = { typ = "JWT", alg = "HS256" }, payload = { -- 自定义数据 userid = "", -- 用户id username = "", -- 用户名 role_id = "", -- 角色id role_name = "", -- 角色名称 --iss = "your_issuer", -- 签发者 --sub = "1234567890", -- 主题 exp = ngx.time() + 3600, -- 过期时间(例如:当前时间+1小时) iat = ngx.time() -- 签发时间 } } --通过参数生存jwt相关的token值 function _M.generateToken(userid, username, role_id, role_name) if userid == nil or username == nil or role_id == nil or role_name == nil then return "" end obj.payload.userid = userid obj.payload.username = username obj.payload.role_id = role_id obj.payload.role_name = role_name --获取的登陆的用户信息,返回tocken local jwt_token = jwt:sign(conf.secret_key, obj) return "Bearer "..jwt_token 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 --验证令牌是否符合要求 local validator = jsonschema.generate_validator(schema) local data = {} data.Authorization = auth_header local ok = validator(data) --如果没有Bearer,则表示令牌无效 if not ok then response["code"] = 401 response["message"] = "令牌格式不正确" return response end --查找令牌中的Bearer前缀字符,并进行截取 local token = string.sub(auth_header,8) --校验令牌 local jwt_obj = jwt:verify(conf.secret_key, token) --如果校验结果中的verified==false,则表示令牌无效 if jwt_obj.verified == false then response["code"] = 401 response["message"] = "令牌无效" return response end --判断token是否超时 if jwt_obj.payload.exp and ngx.time() > jwt_obj.payload.exp then response["code"] = 401 response["message"] = "令牌已过期" return response end --全部校验完成后,说明令牌有效,返回令牌数据 response["code"] = 200 response["message"] = "令牌校验通过" response["body"] = jwt_obj return response end 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, aud = client_id, 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, aud = client_id, 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 return _M