JSON:API 不做什么
JSON:API 完全基于实体(entity)。也就是说,它无法处理业务规则,或执行那些无法被视为 “CRUD” 的操作。诸如注册新账号、登录用户、请求新密码等业务逻辑不属于 JSON:API 的范畴。这些能力中有许多已经由 Drupal 核心提供。
下面给出一份常见需求与解决方案的非完整清单。
相关路径如下:
- /session/token
- /user/register
- /user/login
- /user/login_status
- /user/logout
获取会话令牌(session token)
获取令牌
curl \
--request GET http://drupal.d8/session/token
响应主体会以纯文本(非 JSON)的形式返回一个令牌。
使用令牌
除了会话令牌之外,登录时你还会获得一个 csrf_token
和一个 logout_token
。你需要使用 logout_token
来将用户从系统登出(见下文)。对于可变更的请求(例如 POST、PATCH 和 DELETE),必须提供 csrf_token
或会话令牌。
用户注册
核心提供的 JSON:API 并不支持新用户注册,你可以安装 JSON:API User Resources 模块,以新增与用户相关的 JSON:API 端点,包括注册、重置密码与更新密码等端点。
或者,你也可以使用核心的 REST 模块。若要允许用户通过 REST 注册账号,必须启用 user_registration REST 资源(参见下方的 REST UI 示例)。
curl \
--header "Content-Type: application/json" \
--header "X-CSRF-Token: 57sTS-KS7UoYAWAPyzt0iJmo300CFct3jdKyWM-UiiQ" \
--request POST "https://drupal.d9/user/register?_format=json" \
--data '{"name": {"value": "thename123"}, "pass": {"value": "thepass"}, "mail": {"value": "someone@example.com"}}'
将会话令牌的值作为 X-CSRF-Token 请求头使用。成功的响应应包含一些用户字段值,其中包括新创建用户的 UUID:
{
"uuid" : [ { "value" : "3e75b757-831e-4bf7-bbb6-25b8c50c7ac0" } ]
}
还要注意,响应中并不会包含 “Set-Cookie” 头部,即使站点允许访客自行创建账号也是如此。因此,如果不需要审批或确认,在注册成功后,你可以使用相同的用户名与密码让用户登录。
用户登录
curl \
--header "Content-type: application/json" \
-c cookie.txt \
--request POST "http://drupal.d8/user/login?_format=json" \
--data '{"name":"admin", "pass":"admin"}'
-c cookie.txt
指示 curl 保存一个 cookie。你的响应应类似如下:
{
"csrf_token" : "57sTS-KS7UoYAWAPyzt0iJmo300CFct3jdKyWM-UiiQ",
"logout_token" : "zzRaD8ZgLT1TkG804mYpVVTyM-pgoDm4h9XZ9JHSoCw",
"current_user" : {
"roles" : [
"authenticated",
"administrator"
],
"name" : "admin",
"uid" : "1"
}
}
用户状态
curl \
--header "Content-type: application/json" \
-b cookie.txt \
--request GET "http://drupal.d8/user/login_status?_format=json"
-b cookie.txt
指示 curl 发送(而非保存)上一次请求得到的 cookie。如果你已登录,响应主体会以纯文本(非 JSON)返回 1
;否则返回 0
。
用户登出
curl \
--header "Content-type: application/json" \
-b cookie.txt \
--request POST "http://drupal.d8/user/logout?_format=json&token=zzRaD8ZgLT1TkG804mYpVVTyM-pgoDm4h9XZ9JHSoCw"
以上命令会将由 cookie.txt
所认证的用户登出。请将 logout_token
的值作为 token 查询参数使用。
认证机制
上面的示例只是众多可用认证机制中的一种。你应根据需求评估最合适的机制。
可使用的 Drupal OAuth 模块为 simple_oauth。
参考
更多信息请参阅以下变更记录:
- https://www.drupal.org/node/2720655 (login、login_status 与 logout)
- https://www.drupal.org/node/2752071(register)
关于认证,你也可以考虑使用其他认证协议。
如果你决定在前端使用 JavaScript 应用、在后端使用 Drupal,并采用 “cookie” 方案,浏览器可以为你处理全部的 cookie 存储工作。别忘了:如果你的 JS 应用与 Drupal 站点的域名不同,则必须通过将 SameSite cookie 参数改为 “None” 来允许浏览器存储用户会话 cookie。为此,编辑你的 services.yml
文件并添加如下参数:
parameters:
session.storage.options:
cookie_samesite: None
REST UI
REST UI 贡献模块允许配置核心 REST 模块的资源。下面看看如何使用该模块启用用户注册:
- 安装并启用 REST UI 模块后,前往 /admin/config/services/rest 配置页面,启用 “User registration” 资源。编辑该资源,并例如启用 POST 方法、JSON 格式与 Cookie provider。将粒度(granularity)切换为 “method” 还能让你按请求方法分别设置格式与提供者。
- 然后,在 /admin/people/permissions/module/rest 为匿名用户授予 “Access POST on User registration resource” 权限。
- 最后,确保访客能够在 /admin/config/people/accounts 创建账号。
文章来自 Drupal 文档。