使用Directus updateMe SDK函数更新NextJS当前用户失败排查
问题解决:Directus updateMe SDK 函数无法更新用户信息
核心问题分析
结合你提供的代码和排查情况,问题集中在认证令牌未附加到SDK客户端、客户端实例重复创建以及响应结构判断错误这几个关键点,以下是具体修复方案:
1. 认证令牌缺失(最关键)
你的createDirectus实例没有附加用户认证信息,updateMe接口需要当前登录用户的会话令牌才能完成鉴权。登录注册接口本身是生成令牌的,而更新接口必须携带已有的有效令牌。
修复代码:
在客户端初始化时添加认证处理,并从NextAuth或本地存储中获取用户的Directus令牌:
'use client' import { useRouter } from "next/navigation"; import { useState, useEffect } from "react" import { createDirectus, rest, updateMe, authentication } from '@directus/sdk'; import { useSession } from "next-auth/react"; export default function ProfilEdit({ userContent, userId }) { const router = useRouter(); const { data: session } = useSession(); const [loading, setLoading] = useState(false); const [formData, setFormData] = useState({ first_name: userContent?.first_name || "", last_name: userContent?.last_name || "", email: userContent?.email || "", }); const [error, setError] = useState(""); // 缓存客户端实例,避免每次渲染重建导致会话丢失 const client = createDirectus('*****MYDIRECTUSURL') .with(authentication('json')) .with(rest()); // 登录后自动注入令牌 useEffect(() => { if (session?.user?.directusToken) { client.setToken(session.user.directusToken); } }, [session]); const handleInputChange = (e) => { setFormData({ ...formData, [e.target.name]: e.target.value, }); }; const handleFormSubmit = async (e) => { e.preventDefault(); setLoading(true); try { // updateMe直接返回更新后的用户对象,无外层data字段 await client.request(updateMe(formData)); router.push('/dashboard'); } catch (error) { // 打印详细错误信息,精准定位问题 console.error('更新失败详情:', error.response?.data || error.message); setError(`更新失败: ${error.response?.data?.errors?.[0]?.message || '未知错误'}`); } setLoading(false); }; }
2. 响应结构判断错误
Directus的updateMe接口返回的是直接的用户对象,而非{ data: ... }结构,你原代码中的if (response.data)判断会永远不成立,导致错误提示误触发。
3. 客户端实例重复创建
在组件内部每次渲染都会重新创建client实例,容易导致会话状态丢失,用固定实例或缓存可以解决这个问题(上述代码已处理)。
额外排查点
- 检查表单输入框的
name属性是否与formData的键完全一致(比如first_name不能写成firstName) - 确认NextAuth中正确存储了Directus会话令牌,且令牌未过期
验证步骤
- 修复后打开浏览器控制台,查看catch中的详细错误信息,根据Directus返回的错误码(如401、403)进一步定位问题
- 确认表单提交时,请求头中包含
Authorization: Bearer <你的令牌>
内容的提问来源于stack exchange,提问作者n1k1dk
相关产品推荐
相关产品推荐

