Strapi JWT授权失效调用/users/me返回401/500错误问题求助
Strapi 登录后调用 /users/me 接口返回401授权失败问题
早上好,
我在我的strapi项目中遇到了一个奇怪的问题。我使用标准用户模型,在用户个人资料页通过/users/me接口查询用户信息,上周这一功能还运行正常,但今天早上我尝试登录时,授权功能突然失效了。我是通过以下代码实现用户登录的:
.... async submitForm() { axios.post('http://localhost:1337/auth/local', { 'identifier': this.email, 'password': this.password }) .then((response) => { const { jwt, user } = response.data; window.localStorage.setItem('jwt', jwt); window.localStorage.setItem('userData', JSON.stringify(user)); router.push('/dashboard'); }) .catch((e) => { this.$store.commit('LOGIN_ERROR', e) }); }, ...
登录后会重定向到仪表盘页面,仪表盘会通过如下代码调用/users/me接口:
let token = localStorage.jwt; axios.get(`http://localhost:1337/users/me`, { headers: { Authorization: `Bearer ${token}` } }) .then((response) => { console.log(response.data); })
几天前这段代码还运行正常,请求中使用的token变量确实是登录后后端返回的令牌,但现在strapi控制台抛出了如下错误:
[2021-10-16T07:16:52.568Z] debug GET /users/me (5 ms) 500 [2021-10-16T07:17:03.231Z] debug POST /auth/local (76 ms) 200 [2021-10-16T07:17:24.915Z] error TypeError: Cannot read property 'type' of null at module.exports (/home/user/WebstormProjects/strapi-project/node_modules/strapi-plugin-users-permissions/config/policies/permissions.js:35:14) at async /home/user/WebstormProjects/strapi-project/node_modules/strapi-utils/lib/policy.js:68:5 at async serve (/home/user/WebstormProjects/strapi-project/node_modules/koa-static/index.js:59:5) at async /home/user/WebstormProjects/strapi-project/node_modules/strapi/lib/middlewares/parser/index.js:48:23 at async /home/user/WebstormProjects/strapi-project/node_modules/strapi/lib/middlewares/xss/index.js:26:9
我最初猜测是axios的问题,比如请求中没有正确传递token,因此我用webstorm的http客户端做了同样的测试:
POST http://localhost:1337/auth/local Content-Type: application/json { "identifier": "test@test.com", "password": "..." }
该请求正常返回用户信息和令牌:
"jwt": "<TOKEN>",
但是当我使用该令牌做用户认证时,请求返回401状态码:
GET http://localhost:1337/users/me Authorization: "Bearer <token>" Accept: application/json
返回内容如下:
{ "statusCode": 401, "error": "Unauthorized", "message": "Invalid token." }
我花了一小时排查问题,最后发现后端中该用户没有被分配authenticated角色,当我在后端手动为用户分配该角色后,授权请求就恢复正常了。请问有人知道这是什么原因导致的吗?按照我的理解,向/auth/local发送合法凭证请求时,用户的角色应该会自动变更为Authenticated,几天前这一逻辑还运行正常,我是不是遗漏了什么配置?
问题原因及解决方案
该报错核心是Strapi权限校验时读取用户关联的角色对象为空,触发空指针异常,最终返回401,常见诱因有三类:
- 默认用户角色配置被修改
Strapi 用户权限插件默认会给所有新注册用户分配Authenticated角色,如果你近期调整过后台配置:进入「设置→用户与权限插件→角色→右上角高级设置」,查看默认角色是否被改为空,或者配置同步、环境迁移时覆盖了该配置项,就会出现新注册用户无角色的问题。 - 数据库角色关联被清空
如果近期做过数据库迁移、用户表字段修改、批量更新用户的脚本,或是测试环境脏数据同步到了当前环境,都会导致已有用户的role关联字段变为null,对应你看到的Cannot read property 'type' of null报错。 - 自定义生命周期逻辑异常
如果你重写过/auth/local接口逻辑,或是给用户模型加了beforeCreate/beforeUpdate生命周期钩子,里面对role字段的赋值逻辑出问题,也会导致用户角色没有被正确赋值。
对应的修复和排查步骤:
- 先恢复默认角色配置:进入上述提到的角色高级设置页,确认默认角色选中
Authenticated并保存,测试新注册用户是否自动分配角色。 - 批量修复存量无角色用户:如果有大量用户丢失角色,可以直接执行SQL更新语句(注意替换自己的表前缀):
UPDATE users SET role = (SELECT id FROM up_roles WHERE type = 'authenticated') WHERE role IS NULL;
- 回查近期变更:排查近一周内对用户模型、权限配置、生命周期钩子的修改,如果用了配置同步插件,回滚近期的权限配置变更后再测试。
内容的提问来源于stack exchange,提问作者derelektrischemoench
相关产品推荐
相关产品推荐

