如何解决MercadoLibre API OAuth2.0登录时的code_verifier必填参数错误
解决MercadoLibre API认证时的
code_verifier必填错误 我用下面的Python代码做MercadoLibre API认证,按官方文档步骤操作后,一直收到400错误:
import requests url = 'https://api.mercadolibre.com/oauth/token' payload = {'grant_type': 'authorization_code', 'client_id': app_id, 'client_secret': client_secret, 'code': code_url, 'redirect_uri': uri} headers = {'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded'} response = requests.post(url, headers=headers, data=payload) #json_data = response.json() if response.status_code == 200: token = response.json()['refresh_token'] print('Refresh Token:', token) access_token = response.json()['access_token'] print('Access Token:', access_token) if len(token) > 15: url = uri payload = {'usecli_token': token} response2 = requests.post(url, data=payload) # 列出发布类型数据 url = 'https://api.mercadolibre.com/sites/MLA/listing_prices?price=100' headers = {'Authorization': 'Bearer ' + token} response2 = requests.get(url, headers=headers) precios = response2.json() for precio in precios: print(precio) else: print('获取访问令牌出错:', response.status_code) print(response.text)
错误提示:
{"cause":,"error":"invalid_request","error_description":"code_verifier is a required parameter","status":400}
问题原因
MercadoLibre现在要求OAuth2认证使用PKCE流程,如果你在**获取授权码(code)**的环节中使用了code_challenge参数,那在换取token时必须配套提供对应的code_verifier参数,你的代码里正好缺这个。
解决步骤
生成PKCE所需的验证串
首先要生成一对配套的code_verifier和code_challenge,代码示例:import secrets import hashlib import base64 # 生成code_verifier:43-128位的随机字符串 code_verifier = secrets.token_urlsafe(96) # 长度符合要求 # 生成code_challenge:对code_verifier做SHA256哈希后Base64URL编码 code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode()).digest()).decode().rstrip('=')注意:这对值要保存好,获取授权码和换取token都要用同一组。
获取授权码时携带PKCE参数
跳转到MercadoLibre授权页面时,要在URL里加上code_challenge和code_challenge_method=S256参数。修改token换取请求
在原代码的payload里添加code_verifier参数:payload = {'grant_type': 'authorization_code', 'client_id': app_id, 'client_secret': client_secret, 'code': code_url, 'redirect_uri': uri, 'code_verifier': code_verifier} # 新增这个参数
修改后的完整代码示例
import requests import secrets import hashlib import base64 # 生成PKCE验证串(注意:如果已经在获取授权码时生成过,直接用那组值即可,不要重复生成) code_verifier = secrets.token_urlsafe(96) code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode()).digest()).decode().rstrip('=') # 换取token的请求 url = 'https://api.mercadolibre.com/oauth/token' payload = {'grant_type': 'authorization_code', 'client_id': app_id, 'client_secret': client_secret, 'code': code_url, 'redirect_uri': uri, 'code_verifier': code_verifier} headers = {'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded'} response = requests.post(url, headers=headers, data=payload) if response.status_code == 200: refresh_token = response.json()['refresh_token'] print('Refresh Token:', refresh_token) access_token = response.json()['access_token'] print('Access Token:', access_token) if len(refresh_token) > 15: url = uri payload = {'usecli_token': refresh_token} response2 = requests.post(url, data=payload) # 列出发布类型数据 url = 'https://api.mercadolibre.com/sites/MLA/listing_prices?price=100' headers = {'Authorization': 'Bearer ' + access_token} # 修正:这里应该用access_token而非refresh_token response2 = requests.get(url, headers=headers) precios = response2.json() for precio in precios: print(precio) else: print('获取访问令牌出错:', response.status_code) print(response.text)
额外注意
原代码里调用listing_prices接口时用了refresh_token作为Bearer令牌,这是错误的,应该使用access_token,上面的代码已经修正了这个问题。
内容的提问来源于stack exchange,提问作者Yavis
相关产品推荐
相关产品推荐

