球拍 - 无法检索 Spotify 访问令牌:“不支持的 grant_type”

Posted

技术标签:

【中文标题】球拍 - 无法检索 Spotify 访问令牌:“不支持的 grant_type”【英文标题】:Racket - Can't retrieve Spotify access token: "unsupported grant_type" 【发布时间】:2018-03-15 08:48:41 【问题描述】:

我正在尝试获取 Spotify API 访问令牌。 根据 Spotify API 网站的这些说明:

请求将在请求正文中包含参数:

grant_type - 设置为“client_credentials”。

此 POST 请求的标头必须包含以下参数:

授权 - 包含客户端 ID 和客户端密钥的 Base 64 编码字符串。该字段的格式必须为:Authorization: Basic <base64 encoded client_id:client_secret>

这通常通过向 accounts.spotify.com 发出 POST 请求来完成,如下所示:

curl -X "POST" -H "Authorization: Basic ZjM4ZjAw...WY0MzE=" -d grant_type=client_credentials https://accounts.spotify.com/api/token

屈服: "access_token": "NgCXRKc...MzYjw", "token_type": "bearer", "expires_in": 3600,

我正在尝试像这样在 Racket 中实现它:

http.rkt

#lang racket

(require net/http-client net/uri-codec)

(define (post hc endpoint data headers)
  (define data-encoded (alist->form-urlencoded data))
  (http-conn-send!
    hc endpoint
    #:method "POST"
    #:data data-encoded
    #:headers
      (list
        "Content-Type: application/x-www-form-urlencoded"
        (format "Content-Length: ~a" (string-length data-encoded))
        headers)))

(provide (all-defined-out))

client.rkt

#lang racket

(require
  net/base64 net/http-client net/url-connect
  racket/bytes racket/port
  "http.rkt")

(struct spotify-client (id secret))

(define (hc) (http-conn-open "accounts.spotify.com" #:ssl? #t))

(define (gen-access-token hc client)
  (let* ([credentials (string-append (spotify-client-id client) ":" (spotify-client-secret client))]
        [enc (bytes->string/utf-8 (base64-encode (string->bytes/utf-8 credentials)))]
        [auth (string-append "Authorization: Basic " enc)]
        [data (list (cons 'grant_type "client_credentials"))])
    (post hc "/api/token" data auth)
    (let-values ([(status-line header-list in-port) (http-conn-recv! hc)])
      (displayln (port->string in-port)))))

(provide (all-defined-out))

main.rkt

#lang racket

(require "client.rkt")

(let ([client (spotify-client "<client-id>" "<client-secret>")]
      [hc (hc)])
  (gen-access-token hc client))

但我从 Spotify API 收到的响应是

"error":"unsupported_grant_type","error_description":"grant_type must be client_credentials, authorization_code or refresh_token"

这很奇怪,因为它告诉我我的grant_type 不受支持,即使我的grant_type 是client_credentials(请参阅我何时在(list (cons 'grant_type "client_credentials")) 上调用alist-&gt;form-urlencoded)。这可能是什么原因造成的?

【问题讨论】:

spotify 是否有可用于测试我的答案的测试令牌?还是我必须要一个? (无论哪种方式都可以。:)) @LeifAndersen 我不相信有测试令牌 - 您必须从 the spotify developer site 获取客户端 ID 和客户端密钥。 【参考方案1】:

更新:我无法使用 Racket 的 HTTP 库使代码工作,但当我切换到使用 simple-http 包时它工作了:

(define spotify
  (update-headers
    (update-ssl
      (update-host json-requester "accounts.spotify.com") #t)
   (list
    "Content-Type: application/x-www-form-urlencoded"
    "Authorization: Basic ...")))
(define response (json-response-body (post spotify "/api/token" #:data "grant_type=client_credentials")))
(displayln (hash-ref response 'access_token))

【讨论】:

以上是关于球拍 - 无法检索 Spotify 访问令牌:“不支持的 grant_type”的主要内容,如果未能解决你的问题,请参考以下文章

Spotify API - 在授权过程中检索访问令牌时出错

Spotify API - 在 Google Apps 脚本中检索有效的访问令牌

无法从 Spotify API 获取访问令牌

Spotify Web API 无法获取访问令牌

Spotify API php - 无法请求数据并获取访问令牌

Spotify 会话更新问题