【问题标题】:Clojure, Compojure-api: Access Request headersClojure,Compojure-api:访问请求标头
【发布时间】:2018-01-01 13:32:39
【问题描述】:

我正在尝试实现请求端点身份验证。为此,我想从请求标头中访问 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 端点。

【问题讨论】:

    标签: clojure ring compojure-api


    【解决方案1】:

    Compojure 对参数有自定义解构语法(即,不同于 Clojure 本身)。你可以bind the whole request map使用关键字: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

    【讨论】:

    • 感谢您的快速帮助。
    • 我已经发布了我的问题的答案。你能看看吗?
    【解决方案2】:

    我已经找到了解决问题的办法。请在此处查看解决方案。

    (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 吗?

    【讨论】:

    • 如果你正在构建令牌/JWT/?授权,也许先看看现成的 Ring 授权模块,比如buddy-auth。我认为您对“访问请求标头”的原始问题有答案。如果您没有提供与其他(在本例中是我的)答案基本相同的内容,我也将不胜感激。
    • @Srini 我不会称它为“不聪明的方式”,如果它足够聪明的话。不过,获取标头值的更短的方法是通过:header-params 机制。访问令牌之类的东西通常是通过 ring 中的中间件完成的,因为您通常需要跨多个路由的逻辑。
    【解决方案3】:

    [compojure.api.sweet :refer [defroutes GET PUT context]] 这样的 Compojure Sweet API 函数让我们可以绑定整个请求或绑定选择标头。在[:as request] 下面的 sn-p 中,我可以使用整个请求。

      (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. squiglies {...} 使得 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 的人在记录你在那里可以做的一切方面做得并不好。浏览他们的示例,您会发现类似的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-13
      • 2019-12-26
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 2015-10-01
      相关资源
      最近更新 更多