From 5095f35e122147e15e01b8f8bfd8600bc275b910 Mon Sep 17 00:00:00 2001 From: wanglei <34475144@qqcom> Date: Sun, 16 Nov 2025 22:38:49 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0refresh=5Ftoken=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=EF=BC=8C=E5=B9=B6=E7=BC=96=E5=86=99=E9=83=A8=E5=88=86?= =?UTF-8?q?=E4=B8=9A=E5=8A=A1=E9=80=BB=E8=BE=91=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/service/oauth/oauth.lua | 21 ++++++++++----------- src/util/client.lua | 37 +++++++------------------------------ 2 files changed, 17 insertions(+), 41 deletions(-) diff --git a/src/service/oauth/oauth.lua b/src/service/oauth/oauth.lua index e3444fb..523b446 100644 --- a/src/service/oauth/oauth.lua +++ b/src/service/oauth/oauth.lua @@ -13,6 +13,7 @@ local authcode = require("util.authcode") local token = require("util.token") local client = require("util.client") local conf = require("config") +local red = require("share.redis") local _M = {} @@ -170,7 +171,7 @@ local function authorizateCode(args) -- 生成新 Refresh Token(滚动刷新) local new_refresh_token = token.generate_refresh_token(priv_key, user_id, client_id, scope) --创建用户和应用id的刷新token - client.createRefreshToken(user_id, client_id) + client.createRefreshToken(user_id, client_id, new_refresh_token) -- 生存id_token local new_id_token = token.generate_id_token(priv_key, user_id, client_id, scope) --ngx.say("Generated JWT: ", jwt_obj) @@ -202,22 +203,20 @@ local function authorizateRefresh(args) return end -- 2.验证并消费 refresh_token(滚动刷新:生成新的 rt) - local rt_data, err = client.consumeRefreshToken(res.refresh_token, res.client_id, true) + local rt_data, err = client.consumeRefreshToken(args.refresh_token, args.client_id, true) if not rt_data then ngx.log(ngx.ERR, "refresh_token 验证失败: ", err) ngx.exit(ngx.HTTP_BAD_REQUEST) end - - -- 生成新的 access_token 和 id_token - local userinfo = { - sub = rt_data.sub, - name = "Test User", - email = "test@example.com" - } -- 3.生成新 Access Token - local new_access_token = token.generate_access_token(priv_key, user_id, client_id, scope) + local priv_key = conf.secret_key + local new_access_token = token.generate_access_token(priv_key, rt_data.sub, args.client_id, rt_data.scope) + --存储到redis中,并设置有效期时间 + rt_data.revoked = true + red:set("oidc:refresh_token:"..new_access_token, cjson.encode(rt_data)) + red:expire("oidc:refresh_token:"..new_access_token, conf.refresh_token_ttl) -- 生存id_token - local new_id_token = token.generate_id_token(priv_key, user_id, client_id, scope) + local new_id_token = token.generate_id_token(priv_key, rt_data.sub, args.client_id, rt_data.scope) --ngx.say("Generated JWT: ", jwt_obj) local ret = {} ret.access_token = new_access_token diff --git a/src/util/client.lua b/src/util/client.lua index a7d3d3f..daa68fa 100644 --- a/src/util/client.lua +++ b/src/util/client.lua @@ -11,7 +11,7 @@ local conf = require("config") local _M = {} -- 客户端登录进行存储 -function _M:create(userid, client_id, redirect_uris) +function _M.create(userid, client_id, redirect_uris) local client_str = {} client_str.userid = userid client_str.client_id = client_id @@ -42,18 +42,9 @@ function _M.validate(client_id, redirect_uri) return client end --- 生成随机 refresh_token(64字节,更长更安全) -local function generate_refresh_token() - local random_bytes = random.bytes(64, true) -- 强随机数 - return str.to_hex(random_bytes) -end - -local str = require "resty.string" -local random = require "resty.random" - -- 存储 refresh_token(关联用户、客户端、过期时间) -function _M.createRefreshToken(sub, client_id) - local rt = generate_refresh_token() +function _M.createRefreshToken(sub, client_id, refresh_token) + local rt = refresh_token local rt_data = { sub = sub, -- 用户唯一标识 client_id = client_id, -- 客户端ID @@ -62,7 +53,7 @@ function _M.createRefreshToken(sub, client_id) } -- 存储在 Redis:key=oidc:refresh_token:{rt} - local ok, err = red:set("oidc:refresh_token:" .. rt, cjson.encode(rt_data)) + local ok, err = red:set("oidc:refresh_token:"..rt, cjson.encode(rt_data)) if not ok then return nil, err end @@ -95,24 +86,10 @@ function _M.consumeRefreshToken(rt, client_id, rolling) if rt_data.revoked then return nil, "refresh_token 已吊销" end + -- 吊销旧的 refresh_token + red:expire("oidc:refresh_token:"..rt, 0) -- 立即过期 - -- 滚动刷新:生成新的 refresh_token,吊销旧的 - local new_rt = nil - if rolling then - new_rt, err = _M.create(rt_data.sub, client_id) - if not new_rt then - return nil, "生成新 refresh_token 失败: " .. (err or "") - end - -- 吊销旧的 refresh_token - rt_data.revoked = true - red:set("oidc:refresh_token:" .. rt, cjson.encode(rt_data)) - red:expire("oidc:refresh_token:" .. rt, 0) -- 立即过期 - end - - return { - sub = rt_data.sub, - new_refresh_token = new_rt -- 新的 refresh_token(若滚动刷新) - } + return rt_data end return _M \ No newline at end of file