如何在Clojure中使用Goodreads配置OAuth

时间:2015-10-03 08:57:14

标签: xml api oauth clojure compojure

我正在尝试配置OAuth,以使用它来使用Clojure和Compojure框架从Goodreads API访问数据。我基本上想得到一个Goodreads成员所拥有的朋友列表。我应该提一下,我是Clojure的新手,也是OAuth的新手,一般来说是API身份验证,所以如果可以尽可能简单地解释,我真的很感激。

我试图在线找到答案,但无法找到一个可以帮助我的网站,因为许多网站都处理特定的OAuth API配置,而且在配置OAuth访问方面,这些配置似乎与API有很大不同。此外,他们中很少有人使用Clojure来解释OAuth API配置,并且那些在特定API访问所需的内容方面确实存在差异。 Goodreads API页面也没有用。最后,我找到了this question的答案,并尝试将其用作模板来配置对Goodreads API的OAuth访问。它使用了我尝试使用的clj-oauth和上述问题的答案,因为简单地用Goodreads地址替换该问题的答案中的数据不起作用。这就是我现在所拥有的,但它只返回401错误,我不知道我做错了什么:

(def okey "goodreads-key")

(def osecret "goodreads-secret")

(def consumer (oauth/make-consumer okey
                                   osecret
                                   "http://www.goodreads.com/oauth/request_token"
                                   "http://www.goodreads.com/oauth/access_token"
                                   "http://www.goodreads.com/oauth/authorize"
                                   :hmac-sha1))

(def request-token (oauth/request-token consumer nil))

(oauth/user-approval-uri consumer 
                         (:oauth_token request-token))

(def access-token-response (oauth/access-token consumer 
                                               request-token
                                               nil))

(defn test-get []
  (let [credentials (oauth/credentials consumer
                                       (:oauth_token access-token-response)
                                       (:oauth_token_secret access-token-response)
                                       :GET
                                       "https://www.goodreads.com/friend/user/user-id-number?format=xml")]
    (http/get "https://www.goodreads.com/friend/user/user-id-number?format=xml" {:query-params credentials})))

clj-oauth在客户端示例中说在请求令牌中应该有一个回调uri,在access-token-response中应该有一个验证者,但由于我不熟悉OAuth,我把nil放在那里。 / p>

上述问题的答案并未使用我的代码中的以下几行:

(def request-token (oauth/request-token consumer nil))

(oauth/user-approval-uri consumer 
                         (:oauth_token request-token))

(def access-token-response (oauth/access-token consumer 
                                               request-token
                                               nil))

随后不使用“http://www.goodreads.com/oauth/request_token”                                    “http://www.goodreads.com/oauth/access_token”                                    consumer中的“http://www.goodreads.com/oauth/authorize”地址也不使用(:oauth_token访问令牌响应)                                        {:1}}中的(:oauth_token_secret access-token-response),但用test-get替换这些值,但由于它不起作用,我试图将它与clj-oauth github页面上提到的示例结合起来如上所述,但它仍然无效。

我只是想从Goodreads API获取成员朋友列表的XML响应,并且非常感谢任何配置这一点的帮助。

1 个答案:

答案 0 :(得分:1)

所以我的project.clj看起来像这样:

:dependencies [[org.clojure/clojure "1.6.0"]
                 [clj-oauth "1.5.2"]
                 [clj-http "1.1.2"]]

示例代码:

(ns scratch.core
  (:require [oauth.client :as oauth]
            [clj-http.client :as http]))

(def consumer-key "your_key")
(def consumer-secret "your_secret")

;Step 1: Create an oath consumer object
(def consumer (oauth/make-consumer consumer-key
                                   consumer-secret
                                   "https://www.goodreads.com/oauth/request_token"
                                   "https://www.goodreads.com/oauth/access_token"
                                   "https://www.goodreads.com/oauth/authorize"
                                   :hmac-sha1))
;Step 2: Create a request token.  These can only be used once.  They usually expire as well.
(def request-token (oauth/request-token consumer nil))

;Step 3:  Have the goodreads user approve your application.  They can approve your application by visting the url
; produced by the call below.
(oauth/user-approval-uri consumer
                         (:oauth_token request-token))

;Step 4:  Once the goodreads user has approved your application, you can exchange the request token for an access token.
;An access token is per-user.  Goodreads in particular will only issue 1 per user, so don not lose this access token.
(def access-token-response (oauth/access-token consumer
                                               request-token
                                               nil))

;Step 5: Get the user id of the user who approved your application.
;you can parse the user id out from this.  I used clojure.zip, clojure.data.zip.xml, and clojure.data.xml to parse this out.
(defn get-user-id []
  (let [url "https://www.goodreads.com/api/auth_user"
        credentials (oauth/credentials consumer
                                       (:oauth_token access-token-response)
                                       (:oauth_token_secret access-token-response)
                                       :GET
                                       url)]
    (http/get url {:query-params credentials})))

(get-user-id)

;Step 6: Get the friends of the user.
(defn get-friends [user-id]
  (let [url (str "https://www.goodreads.com/friend/user/" user-id)
        params {:format "xml"}
        credentials (oauth/credentials consumer
                                       (:oauth_token access-token-response)
                                       (:oauth_token_secret access-token-response)
                                       :GET
                                       url
                                       params)]
    (http/get url {:query-params (merge credentials params)})))

(get-friends <a user id>)

编辑:

好的,我重申了上面的确切代码(编辑了api密钥和用户ID)并且100%确定它有效。我强烈建议创建一个一次性Goodreads帐户来测试。

这是screenshot of a successful request