如何用R连接哥白尼陆地监测服务API及认证问题排查
解决R语言连接CLMS API的JWT签名问题
我在用R语言对接哥白尼陆地监测服务(CLMS)API下载数据时,已经把生成好的token存到了land-copernicus.json文件里。按照CLMS的API认证流程写代码,用httr2库生成JWT授权凭证、请求访问令牌的时候,先后踩了两个400错误的坑:
- 第一个:
Missing grant_type - 第二个:
仅支持RS256签名算法
后来测试发现,用Python生成的grant拿到R里请求就能正常跑,所以确定问题出在httr2::jwt_encode_hmac这个方法上。
问题根源
CLMS API要求JWT必须用**RS256(RSA-SHA256)**非对称签名算法,但httr2::jwt_encode_hmac是基于HMAC的对称加密(比如HS256),完全不符合API的签名要求,这就触发了“仅支持RS256”的错误。而之前的“Missing grant_type”,大概率是因为JWT格式不对,服务端解析不出正确的授权参数导致的。
解决方案
换用支持RSA签名的jose包来生成符合要求的JWT,步骤如下:
- 读取本地的token文件,提取私钥:
library(jsonlite) clms_token <- fromJSON("land-copernicus.json") private_key <- openssl::read_pem(clms_token$private_key, password = "")
- 构造JWT的payload和header,明确指定RS256算法:
library(jose) # 构造payload,参数要符合CLMS的要求 payload <- list( iss = clms_token$client_id, sub = clms_token$client_id, aud = "https://identity.clms.eu/auth/realms/CLMS/protocol/openid-connect/token", exp = as.integer(Sys.time()) + 3600 # 设置1小时有效期 ) # 指定签名算法为RS256 header <- list(alg = "RS256", typ = "JWT")
- 生成RS256签名的JWT:
jwt <- jwt_encode_sig(payload, private_key, header = header)
- 用这个JWT请求访问令牌:
library(httr2) token_req <- request("https://identity.clms.eu/auth/realms/CLMS/protocol/openid-connect/token") %>% req_body_form( grant_type = "client_credentials", client_assertion_type = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", client_assertion = jwt ) %>% req_perform() # 提取返回的访问令牌 access_token <- resp_body_json(token_req)$access_token
这样生成的JWT完全符合CLMS API的签名要求,同时正确传递了grant_type参数,之前的两个错误就能解决了。
内容的提问来源于stack exchange,提问作者mistral
相关产品推荐
相关产品推荐

