首页 > 解决方案 > HTTP 错误 401:在 Python 3.8 中使用 urllib 库调用 Rest API 时出现未经授权的问题

问题描述

我正在使用 Python 3.8 中的 OAuth 2.0 调用启用公共的 API,以便使用 AWS Lambda 函数将 json 响应保存在 AWS-S3 中。我面临错误 HTTP 错误 401:未经授权。

获取令牌的函数(fnGetToken)有效,我能够在 Postman 中成功使用令牌并能够获得响应。代码在函数 fnGetFeed 处中断,错误消息如下所示。我认为 urllib.request.urlopen(req) 是造成的,但我认为这是标准的。我不是 python 专家,因此请专家分享他们的反馈来解决这个问题。

import json
import base64
import urllib.request
import os
import boto3

def fnGetToken():
    url = os.environ['authurl']
    headers = {}
    key = os.environ['okey']
    secret = os.environ['osecret']
    # auth header will be combination of client id, secret with 'Basic' Auth Header
    authHeader = 'Basic ' + str(base64.b64encode(bytes((key + ':' + secret), 'utf-8')), "utf-8")
    print(authHeader)
    headers['Authorization'] = authHeader
    headers['ContentType'] = 'application/x-www-form-urlencoded;charset=UTF-8'
    data = "grant_type=client_credentials"
    req = urllib.request.Request(url, headers = headers, method = 'POST')
    response = urllib.request.urlopen(req, data.encode('utf-8'))
    respData = response.read()
    data = json.loads(respData)
    return data['access_token']
    
def fnGetFeed(token):
    screenname = os.environ['screenname']
    url = str(os.environ['apiurl']) + screenname
    print("url generated {}".format(url))
    headers = {}
    authHeader = 'bearer ' + token
    print("token passed: ".format(authHeader))
    headers['Authorization'] = authHeader
    req = urllib.request.Request(url, headers = headers, method = 'GET')
    response = urllib.request.urlopen(req)
    respData = response.read()
    data = json.loads(respData)
    return data
    
def lambda_handler(event, context):
    token = fnGetToken()
    print ("Token generated successfully {}".format(token))
    data = fnGetFeed(token)
    print ("response from get feed function {}".format(data))

    
{
  "errorMessage": "HTTP Error 401: Unauthorized",
  "errorType": "HTTPError",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 58, in lambda_handler\n    data = fnGetFeed(token)\n",
    "  File \"/var/task/lambda_function.py\", line 42, in fnGetFeed\n    response = urllib.request.urlopen(req)\n",
    "  File \"/var/lang/lib/python3.8/urllib/request.py\", line 222, in urlopen\n    return opener.open(url, data, timeout)\n",
    "  File \"/var/lang/lib/python3.8/urllib/request.py\", line 531, in open\n    response = meth(req, response)\n",
    "  File \"/var/lang/lib/python3.8/urllib/request.py\", line 640, in http_response\n    response = self.parent.error(\n",
    "  File \"/var/lang/lib/python3.8/urllib/request.py\", line 569, in error\n    return self._call_chain(*args)\n",
    "  File \"/var/lang/lib/python3.8/urllib/request.py\", line 502, in _call_chain\n    result = func(*args)\n",
    "  File \"/var/lang/lib/python3.8/urllib/request.py\", line 649, in http_error_default\n    raise HTTPError(req.full_url, code, msg, hdrs, fp)\n"
  ]
}

谢谢!

标签: lambdapython-3.8

解决方案


推荐阅读