如何在compojure / swagger中验证标头参数?

时间:2015-12-10 18:43:56

标签: validation clojure swagger compojure

在compojure-api中有以下惯用/最佳实践方法吗?

用户使用以下curl调用调用我们的api:

curl https://some/api/v1/example?a=b -H "u: userid" -H "p: auth-ticket"

curl -X PUT https://some/api/v1/other-example -d '{"c":"d"}' -H "u: userid" -H "p: auth-ticket"

我希望能够将up发送到另一个(内部)服务,并验证它们是否构成授权/未过期的票证。

我可以检查中间件中的值(使用wrap-routes包装),但它会在swagger / compojure验证之前锁定,以检查所需的up是否存在

我似乎无法找到将自定义验证结果放入swagger / compojure验证的方法。有没有一个很好的方法来做到这一点,或者我之前是否经过验证?

编辑:我已经在原始的招摇中做了更多的搜索,并且我已经找到了"安全架构对象"和"授权",但我没有看到任何关于如何在clojure / compojure中使用它们的例子。

编辑:代码示例。

(swag/GET* "/item/:item" 
  [item] 
  :summary "item" 
  :path-params [item :- (swag/describe s/Str "The item.")] 
  :description "Get the description of the item." 
  :header-params [ticket :- (swag/describe s/Str "security ticket")
                  userid :- (swag/describe s/Str "user ticket")]
  (ok (find-item item))

(swag/GET* "/item/:item/detailed" 
  [item] 
  :summary "item - detailed" 
  :path-params [item :- (swag/describe s/Str "The item.")] 
  :description "Get a detailed description of the item." 
  :header-params [ticket :- (swag/describe s/Str "security ticket")
                  userid :- (swag/describe s/Str "user ticket")]
  (ok (find-item item :detailed))

我的问题是如何避免在每个端点上反复编写:header-params部分抛出"访问被拒绝&#34 ;如果缺少票证/用户ID,或者它没有验证。

2 个答案:

答案 0 :(得分:0)

目的swagger是定义接口。

如果我理解正确,您正在尝试定义API如何在内部实施凭证验证。这个实现细节。

Swagger不支持定义实现逻辑。它只允许定义'界面'

答案 1 :(得分:0)

您可以结合使用context:middleware来完成此操作。

(swag/context "/item/:item" [item]
  :path-params [item :- (swag/describe s/Str "The item.")]
  :header-params [ticket :- (swag/describe s/Str "security ticket")
                  userid :- (swag/describe s/Str "user ticket")]
  :middleware [wrap-check-headers]

  (swag/GET "/" req
    :summary "item"
    :description "Get the description of the item."
    (ok (find-item item)))

  (swag/GET "/detailed" req
    :summary "item - detailed"
    :description "Get a detailed description of the item."
    (ok (find-item item :detailed))))

您可以定义wrap-check-headers之类的内容:

(defn wrap-check-headers [handler]
  (fn [{{:strs [ticket userid]} :headers :as request}]
    (if (and (= ticket "123") (= userid "456"))
      (handler request)
      (forbidden "authorization header mismatch"))))

这将生成一个Swagger API,如下所示: example swagger api

一个符合要求的API:

$ curl -w '\nstatus:%{http_code}\n' -H Ticket:123 http://localhost:3000/item/abc/
{"errors":{"userid":"missing-required-key"}}
status:400

$ curl -w '\nstatus:%{http_code}\n' -H UserID:456 http://localhost:3000/item/abc/
{"errors":{"ticket":"missing-required-key"}}
status:400

$ curl -w '\nstatus:%{http_code}\n' -H Ticket:Wrong -H UserID:456 http://localhost:3000/item/abc/
authorization header mismatch
status:403

$ curl -w '\nstatus:%{http_code}\n' -H Ticket:123 -H UserID:456 http://localhost:3000/item/abc/
found ("abc")
status:200