由于它与访问特定API有关,因此不可能为此提供可重现的示例 - 提前道歉。我试图通过R访问爱丁堡边缘节日API。documentation说如下:
验证
对API的所有请求都需要访问密钥,并且可以 通过注册获得。这个键,结合签名 如下所述,需要获得对API的任何访问权限。如果你这样做 不提供访问密钥,或提供无效密钥或签名, 服务器将返回
HTTP 403
错误。您的秘密令牌用于计算每个签名的正确签名 API请求,绝不能透露。一旦发布,它永远不会 向后或向前传播。 API服务器保存您的副本 秘密令牌,用于检查您是否已签署每个请求 正确。
您使用HMAC-SHA1算法计算签名:
构建完整的API请求网址,包括您的访问密钥,但不包括服务器域 - 例如
/events?festival=book&key=12345
。看到 关于URL编码的说明。使用sha1算法和您的秘密令牌作为密钥计算网址的hmac哈希值。
将十六进制编码的哈希值附加到您的网址作为签名参数
查询中的网址编码
您应该在对任何参数进行网址编码后计算签名 - 例如,要搜索标题“布朗夫人”,你首先要建立 网址
/events?title=Mrs%20Brown&key=12345
,然后签署此字符串 并附上签名。签名编码
某些语言 - 尤其是C# - 默认使用UTF-16编码哈希值。 确保您的签名以纯ASCII十六进制编码,否则不会 有效的。
到目前为止我所尝试的内容如下:
library(digest)
library(jsonlite)
source("authentication.R") # credentials stored here
创建查询字符串
query <- paste0('/events?festival=demofringe&size=20&from=1&key=', API_KEY)
创建散列查询
sig <- hmac(SECRET_SIGNING_KEY, query, algo="sha1")
创建最终网址
url <- paste0('https://api.edinburghfestivalcity.com', query, '&signature=', sig)
提交给API
results <- fromJSON(url)
我收到错误:
Error in open.connection(con, "rb") : HTTP error 417.
我不确定签名是否按照文档进行ASCII编码。有谁知道如何调试这种情况?我已尝试iconv()
尝试转换编码,当我在字符对象上调用Encoding()
时,它返回"unknown"
。我还尝试将两个文件保存在RStudio中,并将“save with encoding”设置为ASCII,我尝试使用encoding = "ASCII"
获取身份验证。
顺便提一下,当我将最终的网址粘贴到浏览器中时,我收到以下错误:
Invalid Accept header value. ['application/json', 'application/json;ver=2.0'] are supported
答案 0 :(得分:1)
这是服务器错误。它应该明白
Accept: application/json, text/*, */*
匹配application/json
。请注意,不是修改jsonlite,而是从服务器手动检索响应,然后然后将其提供给jsonlite。
library(httr)
library(jsonlite)
req <- GET(your_url, accept("application/json")
json <- content(req, as = 'text')
data <- fromJSON(json)
答案 1 :(得分:0)
最后,我通过编辑jsonlite::fromJSON()
函数解决了这个问题。即行
curl::handle_setheaders(h, Accept = "application/json, text/*, */*")
我改为
curl::handle_setheaders(h, Accept = "application/json")
然后我还必须指向jsonlite:::
的内部函数。现在它工作正常。