Clojure, Compojure-api: 访问请求头

4

我正在尝试实现请求端点身份验证。为此,我想从请求头中访问accessToken值。

我的GET请求端点是

CURL命令

curl -X GET \
  'http://localhost:3000/hello?id=10' \
  -H 'accesskey: 23423sfsdfsdfsfg' \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -H 'postman-token: f69b34e6-4888-ec31-5fbc-b734e176571b' \
  -d '{
    "artwork": {id" : 1}
}'

HTTP命令

GET /hello?id=10 HTTP/1.1
Host: localhost:3000
Content-Type: application/json
accessKey: 23423sfsdfsdfsfg
Cache-Control: no-cache
Postman-Token: b974719d-5e1d-4d68-e910-e9ca50562b2f

GET方法实现的代码

(defapi app
  (GET ["/hello/:id", :id #"[0-9]+" ] [id]
    (log/info "Function begins from here")
    (def artworkData (logic/artwork-id (->> id (re-find #"\d+") Long/parseLong)))
    (def data (if (not-empty artworkData)
               {:data artworkData :status 200}
               {:data [] :status 201}))
   (ok data)))

我想从请求头中提取accessKey: 23423sfsdfsdfsfg

有没有办法获取该值并在我的GET方法中使用?

我正在使用POSTMAN测试所有API端点。

3个回答

3

Compojure具有用于参数的自定义解构语法(与Clojure proper不同)。您可以使用关键字:as 绑定整个请求映射

(defapi app
  (GET ["/hello/:id", :id #"[0-9]+" ] [id :as request]

如果您只需要请求头,以下内容应该可以实现

(defapi app
  (GET ["/hello/:id", :id #"[0-9]+" ] [id :as {:headers headers}]

请注意,这仍然允许您绑定路径参数id

感谢您的快速帮助。 - Srini
我已经发布了对我的问题的答案。你能看一下吗? - Srini

1
Compojure Sweet API 的函数,如 [compojure.api.sweet :refer [defroutes GET PUT context]],可以让我们绑定整个请求或选择性地绑定头信息。在下面的代码片段中,[:as request] 可以让整个请求对我可用。
  (GET
    "/download/:id"
    [:as request]
    :header-params [{x-http-request-id :- X-Http-Request-Id nil}]
    :path-params [id :- (describe String "The encoded id of the image")]
    :summary "Download the image bytes"
    :description "This endpoint responds 307 - Temporary Redirect to a cacheable presigned S3 URL for the actual bytes."
    (let [http-response (->> request
                             walk/keywordize-keys
                             util/extract-base-url
                             (transform/generate-resource-url (util/decode-key id))
                             status/temporary-redirect)
          expire-time (-> 3 hours from-now coerce/to-date ring-time/format-date)]
      (log/infof "x-http-request-id is %s" x-http-request-id)
      (response/header http-response "Expires" expire-time)))
  1. 向量开头的:header-params [{x-http-request-id :- X-Http-Request-Id nil}]使得请求中"X-HTTP-REQUEST-ID"头的值可以直接作为x-http-request-id在我的函数中使用。
  2. 大括号{...}表示请求中是否存在x-http-request-id头是可选的。
  3. :- X-Http-Request-Id nil这个东西给它一个模式,该模式在其他地方定义,例如(s/defschema X-Http-Request-Id (rss/describe String "Request ID for tracing calls"))

一旦你将它们绑定到名称,你只需要使用这些名称。Compojure的开发人员并没有很好地记录您可以在那里执行的所有操作。请查看他们的示例,您会找到类似于此类的内容。


-1

我已经找到了解决问题的方法。请在这里查看解决方案。

(ns clojure-dauble-business-api.core
  (:require [compojure.api.sweet :refer :all]
            [ring.util.http-response :refer :all]
            [clojure-dauble-business-api.logic :as logic]
            [clojure.tools.logging :as log]
            [clojure-dauble-business-api.domain.artwork]
            [cheshire.core :as json])
  (:import [clojure_dauble_business_api.domain.artwork Artwork]))

(defapi app
  (GET ["/hello/:id", :id #"[0-9]+"] [id :as request]
    (log/info "Function begins from here" request)
    (def jsonString (json/generate-string (get-in request [:headers])))
    (log/info "Create - Access Key  is " (get-in (json/parse-string jsonString true) [:accesskey]))
    (def artworkData (logic/artwork-id (->> id (re-find #"\d+") Long/parseLong)))
    (def data (if (not-empty artworkData)
               {:data artworkData :status 200}
               {:data [] :status 201})))

我认为这不是一个聪明的方式。

你们有人可以看一下我的解决方案并告诉我是否有另一种方法来获取accesskey吗?


3
如果你正在构建 token/JWT/?授权,可能首先应该查看 Ring 的现成授权模块,比如buddy-auth。我认为你已经得到了关于“访问请求头”的原始问题的答案。如果您不提供与其他回答(在这种情况下是我的回答)基本相同的内容,我也会感激。 - Toni Vanhala
@Srini 我不会说这是“不聪明的方式”,如果它能工作,那就足够聪明了。然而,更短的获取头部值的方法是通过:header-params机制。像访问令牌之类的东西通常是通过ring中的中间件来完成的,因为你经常需要在许多路由中使用它的逻辑。 - Bob Kuhar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接