写点什么

Next.js 的一次 cookies 处理过程

作者:麦兜
  • 2024-09-04
    浙江
  • 本文字数:1626 字

    阅读完需:约 5 分钟

这次的这个问题真的困扰了我 4 天. 不过最后还是解决了.

业务场景

我在 frappe 的服务端有 2 个服务, 都是 frappe 标准的服务, 一个是 /api/method/login, 一个是 /api/method/frappe.auth.get_logged_user。


这 2 个服务其实就是完成一次最基本的 Frappe 登录过程。 先通过 username,password 发往服务端做验证。校验通过, 则服务端会生成一个 session。


那么如果通过第 2 个 API 能获取登录的 session 用户名, 则代表登录完成。

1. 正常场景

第一步: 在浏览器里头,或者 postman 里头, 调用了 /api/method/login 的 post 方法, 是能得到正常登陆的.


第二步: 当第一步执行完成, 则再调用 /api/method/frappe.auth.get_logged_user, 我也能得到正常的结果, 请求状态是 200.

2. 正常场景

第一步, 我在 curl 里头, 调用 /api/method/login 的 post 方法, 是能得到正常登陆的.


# 使用 curl 登录并保存 cookie 和 CSRF tokencurl -c cookies.txt -X POST https://foodxz.frappe.cloud/api/method/login \-H "Content-Type: application/json" \-d '{"usr": "goodhawk1@gmail.com", "pwd": "Hhshd&6363hgdj_"}' \-i
复制代码


第二步, 当第一步执行完成, 则再调用 /api/method/frappe.auth.get_logged_user, 我将得到正常的结果


[root@zdevhost Temp]# curl -b cookies.txt -X GET https://foodxz.frappe.cloud/api/method/frappe.auth.get_logged_user \> -H "Content-Type: application/json" \> -iHTTP/1.1 200 OKDate: Mon, 02 Sep 2024 13:16:01 GMTContent-Type: application/jsonContent-Length: 33Connection: keep-aliveVary: Accept-EncodingSet-Cookie: sid=74d88ddfccd063fc1ba7568a84bf7be904ea6c152a4ff2ab243c4725; Expires=Mon, 09 Sep 2024 15:16:01 GMT; Max-Age=612000; xxxx
复制代码

3. 不正常场景.

第一步, 我在 next.js 里头或者 curl 里头, 调用 /api/method/login 的 post 方法, 是能得到正常登陆的.


第二步, 当第一步执行完成, 则再调用 /api/method/frappe.auth.get_logged_user, 我将得不到结果. 返回的结果是 403 FORBIDDEN,


然后我可以看到服务端的 web.log 里头返回如下的内容


File "apps/frappe/frappe/model/db_query.py", line 114, in execute    self.check_read_permission(self.doctype, parent_doctype=parent_doctype)  File "apps/frappe/frappe/model/db_query.py", line 511, in check_read_permission    self._set_permission_map(doctype, parent_doctype)  File "apps/frappe/frappe/model/db_query.py", line 517, in _set_permission_map    frappe.has_permission(  File "apps/frappe/frappe/__init__.py", line 1090, in has_permission    raise frappe.PermissionError frappe.exceptions.PermissionError
复制代码


解决方法是:


对第一个服务产生的 cookies 不直接回传到客户端。 需要手动去维护 cookies。手动维护的 cookies 只要 Key 和 Value, 不需要设置 options。


        const res = await fetch('/api/data', {          method: 'POST',          headers: {            'Content-Type': 'application/json',          },          credentials: 'omit',          mode: 'cors', // 可选参数,指定请求的模式,跨域请求需要设置为'cors'          cache: 'no-cache', // 可选参数,指定请求的缓存模式          redirect: 'follow', // 可选参数,指定重定向的模式          referrerPolicy: 'no-referrer', // 可选参数,指定referrer信息的政策                    body: JSON.stringify({            username: username,            password: password          }),        });
if (!res.ok) throw new Error('Failed to fetch data');
const result = await res.json(); console.log('data', result);
await saveCookieSid(result.cookies[0]); // 设置 cookies await setCookies(result.serializedCookies);
复制代码


用户头像

麦兜

关注

与一只鸟生活在杭州 2023-01-19 加入

企业ERP,企业供应链,业务财务一体化老兵

评论

发布
暂无评论
Next.js的一次cookies处理过程_麦兜_InfoQ写作社区