SuperTokens refreshSession调用报错排查:「刷新令牌未找到」问题解决咨询
解决SuperTokens refreshSession提示"Refresh token not found"的问题
我帮你排查了问题的核心原因,主要是两个配置疏漏导致服务器无法识别请求里的refresh token Cookie,下面是具体的分析和解决方案:
问题根源
- 未挂载SuperTokens的Express中间件:你已经引入了
middleware但没有在Express应用中启用它,这会导致SuperTokens无法解析请求中的Cookie(包括关键的refresh token)。 - CORS配置缺少凭证支持:虽然安装了
cors包,但默认配置不允许携带凭证,即使Postman发送了Cookie,服务器也无法正确接收并处理。
另外补充一点:你手动实现的/refresh路由其实可以省略——SuperTokens的中间件会自动处理你配置的apiBasePath下的/refresh端点(也就是/auth/refresh),遵循官方规范能减少自定义代码的潜在问题。
分步解决方案
1. 正确挂载SuperTokens中间件
在所有路由定义之前,添加SuperTokens的中间件,它负责解析请求Cookie、处理会话相关的底层逻辑:
let app = express(); // 先配置CORS(步骤2内容) // 然后挂载SuperTokens中间件 app.use(middleware()); // 之后再定义你的业务路由 app.get('/login', async (req, res) => { // ... 你的登录逻辑 });
2. 配置CORS允许凭证传递
修改CORS配置,明确允许携带凭证,并包含SuperTokens所需的自定义请求头:
app.use(cors({ origin: "http://localhost:1919", allowedHeaders: ["content-type", ...supertokens.getAllCORSHeaders()], credentials: true, }));
supertokens.getAllCORSHeaders()会自动包含SuperTokens需要的所有特殊头,确保会话相关的请求头能正常传递。
3. 优化refresh路由(可选)
删除你自定义的/refresh路由,直接使用SuperTokens自带的GET /auth/refresh端点(对应你配置的apiBasePath: "/auth"),这是官方推荐的刷新会话方式,能避免自定义代码的潜在错误。
如果坚持保留自定义/refresh路由,只要确保SuperTokens中间件在路由之前挂载即可,这样req对象已经被处理,refreshSession就能找到refresh token。
4. 验证Postman的Cookie设置
确认Postman请求满足以下条件:
- 请求的域名/端口和
apiDomain完全一致(http://localhost:1919) - Cookie列表中存在
sRefreshToken(SuperTokens的刷新token Cookie) - Postman的"Send cookies"选项处于开启状态(可在请求的Cookies标签页查看)
修改后的完整index.js示例
const express = require('express'); const cors = require('cors'); const supertokens = require("supertokens-node"); const Session = require("supertokens-node/recipe/session"); const {middleware, errorHandler} = require("supertokens-node/framework/express"); const {verifySession} = require("supertokens-node/recipe/session/framework/express"); supertokens.init({ framework: "express", supertokens: { connectionURI: "http://localhost:3568", apiKey: "TestTestTest123456789987654321", }, appInfo: { appName: "rezaTest", apiDomain: "http://localhost:1919", websiteDomain: "http://localhost:1919", apiBasePath: "/auth", websiteBasePath: "/auth" }, recipeList: [ Session.init() ] }); let app = express(); // 配置CORS app.use(cors({ origin: "http://localhost:1919", allowedHeaders: ["content-type", ...supertokens.getAllCORSHeaders()], credentials: true, })); // 挂载SuperTokens中间件 app.use(middleware()); app.get('/login', async (req, res) => { await Session.createNewSession(res, '1234'); res.end('logged in'); }) app.get("/is-authorized", verifySession(), (req, res) => { console.log(req.session); if (req.session) { res.end('Authorized!'); } else { res.end('Is not Authorized'); } }); app.use(errorHandler()); app.listen(1919, () => { console.log(`http://localhost:1919`); })
测试验证
- 重启Node.js应用和SuperTokens服务
- 调用
GET /login获取会话Cookie - 等待10秒让access token过期
- 调用
GET /auth/refresh刷新会话,此时应该返回成功 - 再次调用
GET /is-authorized,应该返回Authorized!
内容的提问来源于stack exchange,提问作者Reza Amya
相关产品推荐
相关产品推荐

