REST API 垃圾信息防护和 CAPTCHA 支持
如果模型可以通过 REST API 进行修改,你还必须为所有可能修改可被垃圾信息攻击或与垃圾信息相关属性的 API 端点添加支持。这肯定包括 POST 和 PUT 变更操作,但也可能包括其他操作,例如那些与更改模型的机密/公开标志相关的操作。
为 REST 端点添加支持
主要步骤如下:
-
在你的
resource中添加helpers SpammableActions::CaptchaCheck::RestApiActionsSupport。 -
向更新服务类构造函数传递
perform_spam_check: true。 在创建服务中,它默认设置为true。 -
创建或更新
Spammable模型实例后,调用#check_spam_action_response!, 将创建或更新的实例保存在变量中。 -
识别请求
failure情况的错误处理逻辑, 当创建或更新不成功时。这些表示可能的垃圾信息检测, 这会在Spammable实例中添加错误。 错误通常类似于render_api_error!或render_validation_error!。 -
将现有的错误处理逻辑包装在
with_captcha_check_rest_api(spammable: my_spammable_instance)调用中, 将你保存在变量中的Spammable模型实例作为spammable:命名参数传递。此调用将:- 对模型执行必要的垃圾信息检查。
- 如果检测到垃圾信息:
- 抛出一个带有描述性垃圾信息特定错误消息的 Grape
#error!异常。 - 将相关信息作为错误字段添加到响应中。 有关这些字段的更多详细信息,请参阅 REST API 文档中 解决被检测为垃圾信息的请求 的部分。
- 抛出一个带有描述性垃圾信息特定错误消息的 Grape
如果你使用上面描述的标准 ApolloLink 或 Axios 拦截器 CAPTCHA 支持, 你可以忽略字段细节,因为它们会被自动处理。 如果你尝试直接使用 GraphQL API 来处理失败的潜在垃圾信息检查, 并使用已解决的 CAPTCHA 响应重新提交请求,这些字段就会变得相关。
以下是 snippets 资源上 post 和 put 操作的示例:
module API
class Snippets < ::API::Base
#...
resource :snippets do
# 这个辅助方法提供 `#with_captcha_check_rest_api`
helpers SpammableActions::CaptchaCheck::RestApiActionsSupport
post do
#...
service_response = ::Snippets::CreateService.new(project: nil, current_user: current_user, params: attrs).execute
snippet = service_response.payload[:snippet]
if service_response.success?
present snippet, with: Entities::PersonalSnippet, current_user: current_user
else
# 将常规错误响应包装在 `with_captcha_check_rest_api(spammable: snippet)` 块中
with_captcha_check_rest_api(spammable: snippet) do
# 如果检测到可能的垃圾信息,`#with_captcha_check_rest_api` 会抛出异常
# 让 Grape 通过 `error!` 处理
render_api_error!({ error: service_response.message }, service_response.http_status)
end
end
end
put ':id' do
#...
service_response = ::Snippets::UpdateService.new(project: nil, current_user: current_user, params: attrs, perform_spam_check: true).execute(snippet)
snippet = service_response.payload[:snippet]
if service_response.success?
present snippet, with: Entities::PersonalSnippet, current_user: current_user
else
# 将常规错误响应包装在 `with_captcha_check_rest_api(spammable: snippet)` 块中
with_captcha_check_rest_api(spammable: snippet) do
# 如果检测到可能的垃圾信息,`#with_captcha_check_rest_api` 会抛出异常
# 让 Grape 通过 `error!` 处理
render_api_error!({ error: service_response.message }, service_response.http_status)
end
end
end