使用访问令牌时出现 Gmail API 禁止错误
我正在尝试使用 Gmail 的 API 来获取一些数据。下面是程序的工作流程。首先,我向谷歌服务器提交请求,这样用户就可以给我的应用程序指定权限:
def oauth_connect(request):
if request.method == 'GET' and request.user.is_authenticated():
auth_uri = 'https://accounts.google.com/o/oauth2/auth?response_type=code&scope=https://www.googleapis.com/auth/gmail.compose&client_id={0}&redirect_uri={1}&approval_prompt=force'.format(GOOGLE_CLIENT_ID, HOSTNAME_URI + 'oauth2callback')
return HttpResponseRedirect(auth_uri)
在回调中,我保存了谷歌发送的访问令牌。我本来还期待在响应中看到刷新令牌,但显然没有。
def google_oauth_return(request):
if request.method == 'GET' and request.user.is_authenticated():
# Get the auth code from the GET request
code = request.GET['code']
agent = Agent.objects.get(user=request.user)
# Create a list of 2-tuples for the parameters to send in the POST request back to eventbrite to get the auth token
post_data = [('code', code), ('client_secret', GOOGLE_CLIENT_SECRET), ('client_id', GOOGLE_CLIENT_ID),
('redirect_uri', HOSTNAME_URI + 'oauth2callback'), ('grant_type', 'authorization_code'),
]
# Send POST request and get json sent back
result = urllib2.urlopen('https://accounts.google.com/o/oauth2/token', urllib.urlencode(post_data))
pprint.pprint(result)
# Load the json into a python dict
data = json.load(result)
pprint.pprint(data)
# Get the access token
access_token = data['access_token']
expiration_time = data['expires_in']
if 'refresh_token' in data:
refresh_token = data['refresh_token']
else:
refresh_token = ''
agent.google_access_token = access_token
agent.google_access_token_expiration_time = datetime.utcnow().replace(tzinfo=tz.tzutc()) + timedelta(seconds=int(expiration_time))
agent.google_refresh_token = refresh_token
agent.save()
return HttpResponseRedirect('/profile')
但是,当我使用访问令牌来获取数据时,我遇到了 HTTP 403 禁止访问的错误。
def get_gmail_data(request):
if request.method == 'GET':
agent = Agent.objects.get(user=request.user)
access_token = agent.google_access_token
pprint.pprint(access_token)
expiration_time = agent.google_access_token_expiration_time
# TODO Check if access token expired. tzinfo=tz.utc is used because utcnow returns a offset-naive datetime
# Set up HTTPS request and add access token as a header
get_mail = urllib2.Request('https://www.googleapis.com/gmail/v1/users/me/messages')
get_mail.add_header('Authorization', 'Bearer ' + access_token)
# Open the connection and get the json, turn it into a python dict
gmail_data = urllib2.urlopen(get_mail)
gmail = json.load(gmail_data)
pprint.pprint(gmail)
我对 OAuth 还不太熟悉,如果有人能指出问题所在,那就太好了。
1 个回答
1
根据Google APIs Explorer的信息,你现在使用的OAuth 2.0权限范围是:
https://www.googleapis.com/auth/gmail.compose
… 这个权限范围只允许:
管理草稿和发送邮件
但是你想要做的是:
https://www.googleapis.com/gmail/v1/users/me/messages
也就是说,你想查看邮件。你需要一个合适的权限范围:
https://mail.google.com/
… 这个权限范围允许:
查看和管理你的邮件
所以这个错误信息是完全合理的。你请求并获得了做一件事情的权限,但尝试去做了另一件事情,因此出现了权限错误。