diff --git a/src/service/oauth/oauth.lua b/src/service/oauth/oauth.lua index a60c1da..e8b2083 100644 --- a/src/service/oauth/oauth.lua +++ b/src/service/oauth/oauth.lua @@ -10,6 +10,7 @@ local cjson = require("cjson.safe") local jwt = require "resty.jwt" local rsa = require("util.rsa") local authcode = require("util.authcode") +local token = require("util.token") local _M = {} @@ -137,69 +138,22 @@ function _M:token() end print("token pubkey:", pub_key) local user_id = code_data.user_id - --print("token user_id:", user_id) local client_id = code_data.client_id - --print("token client_id:", client_id) local scope = code_data.scope - --print("token scope:", scope) - local access_token_ttl = 10 * 60 --十分钟 - local refresh_token_ttl = 7 * 24 * 3600 --7天 -- 6 生成新 Access Token - local access_payload = { - sub = user_id, -- 用户ID - client_id = client_id, - scope = scope or "", - exp = ngx.time() + access_token_ttl, - jti = ngx.md5(ngx.time() .. math.random() .. client_id) -- 唯一标识 - } - local new_access_token = jwt:sign(priv_key, { - header = { typ = "JWT", alg = "HS256" }, - payload = access_payload - }) - + local new_access_token = token.generate_access_token(priv_key, user_id, client_id, scope) -- 7 生成新 Refresh Token(滚动刷新) - local refresh_payload = { - sub = user_id, - client_id = client_id, - scope = scope or "", - exp = ngx.time() + refresh_token_ttl, - jti = ngx.md5(ngx.time() .. math.random() * 1000 .. client_id) - } - local new_refresh_token = jwt:sign(priv_key, { - header = { typ = "JWT", alg = "HS256" }, - payload = refresh_payload - }) - + local new_refresh_token = token.generate_refresh_token(priv_key, user_id, client_id, scope) -- 8、生存id_token - -- 创建JWT的payload - local payload = { - iss = request_uri, - sub = user_id, - name = user_id, - iat = os.time(), - exp = os.time() + 3600 - } - -- 使用私钥生成JWT - local jwt_obj = jwt:sign(priv_key, { - header = { - type = "JWT", - alg = "RS256" - }, - payload = payload - }) - if not jwt_obj then - local result = resp:json(0x00001) - resp:send(result) - return - end + local new_id_token = token.generate_id_token(priv_key, user_id, client_id, scope) --ngx.say("Generated JWT: ", jwt_obj) -- 9. 返回结果 local ret = {} ret.access_token = new_access_token ret.token_type = "Bearer" - ret.expires_in = access_token_ttl + ret.expires_in = 10 * 60 ret.refresh_token = new_refresh_token - ret.id_token = jwt_obj + ret.id_token = new_id_token local result = resp:json(ngx.HTTP_OK, ret) resp:send(result) end diff --git a/src/util/token.lua b/src/util/token.lua index a983d73..c654bc2 100644 --- a/src/util/token.lua +++ b/src/util/token.lua @@ -93,4 +93,66 @@ function _M.authorizationToken(auth_header) 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, + client_id = 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, + client_id = 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 \ No newline at end of file