我已经尝试了几天来解决这个问题,但没有取得任何成功。 我有一个Web应用程序,我想与Google Drives API一起使用。 我希望Web应用程序检查是否有可以使用的访问令牌,如果没有重定向到Google,则用户可以登录并授予访问权限。
看似简单的任务,但它让我发疯!我已经检查了Google文档,但它似乎都适用于控制台应用程序
答案 0 :(得分:1)
Google提供了一个界面UserService,用于存储使用该应用程序的用户的详细信息。如果用户未登录,则使用以下命令将用户重定向到登录页面:
response.sendRedirect(userService.createLoginURL(request.getRequestURI()))
稍后或如果用户已登录,请将其重定向到"请求权限"页面使用:
List<String> scopes = Arrays.asList(PlusScopes.PLUS_LOGIN,PlusScopes.PLUS_ME,PlusScopes.USERINFO_EMAIL,PlusScopes.USERINFO_PROFILE......); // Add/remove scopes as per your requirement
List<String> responseTypes = Arrays.asList("code");
GoogleAuthorizationCodeRequestUrl gAuthCode = new GoogleAuthorizationCodeRequestUrl(Google project client id, redirect url, scopes);
gAuthCode.setAccessType("offline");
gAuthCode.setClientId(Google project client id);
gAuthCode.setResponseTypes(responseTypes);
gAuthCode.setApprovalPrompt("force");
authURl = gAuthCode.toURL().toString();
response.sendRedirect(authURl);
确保添加将要使用的API方法的所有必需范围。在用户接受之后,您将不得不使用&#34; / oauth2callback&#34;创建一个servlet。映射以获取授权码。
request.getParameter("code")
在使用获得的代码的同一个servlet中,获取刷新和访问令牌进行休息调用。
URL url = new URL("https://www.googleapis.com/oauth2/v3/token");
HttpURLConnection connection= (HttpURLConnection)url.openConnection();
connection.setRequestMethod("post");
connection.setDoInput(true);
connection.setDoOutput(true);
DataOutputStream dw= new DataOutputStream(connection.getOutputStream());
dw.writeBytes("code="+authorizationCode+"&client_id="+CLIENT_ID+"&client_secret="+CLIENT_SECRET+"&redirect_uri="+REDIRECT_URL+"&grant_type=authorization_code");
dw.flush();
dw.close();
InputStream inputStream= connection.getInputStream();
解析输入流以获取刷新令牌和访问令牌,并将用户重定向到目标网页。
现在您有访问令牌来查询您的api,其范围在授权流程中提供。此外,您还有一个刷新令牌,如果先前发出的访问令牌已过期,则可以使用该令牌重新生成新的访问令牌。
答案 1 :(得分:0)
您应该能够使用HTTP请求和Web应用程序的重定向URL实现OAuthHandshake。您可以在此处查看请求,以查看标题和响应的内容:https://developers.google.com/oauthplayground/
您可以按照自己喜欢的方式存储授权码和令牌。您可以让您的Web应用程序引用这些令牌以查看它们是否已过期。例如:
def getTokenFromFile(self):
creds = self.readCredsFromDisk()
# check if token is expired
expiration_time = datetime.datetime.strptime(creds['token_expiry'], '"%Y-%m-%dT%H:%M:%S.%f"')
if expiration_time < datetime.datetime.now():
self.refreshToken()
# reload creds
creds = self.readCredsFromDisk()
return creds['access_token']
我只编写了一个执行握手的python脚本,并将令牌保存到纯文本文件中。只要脚本向Google API运行某个功能,它就会使用此功能。
刷新功能:
def refreshToken(self):
with open('client_secret.json') as s:
secret = json.load(s)
secret = secret['installed']
creds = self.readCredsFromDisk()
refresh_url = secret['token_uri']
post_data = {'client_id':secret['client_id'],
'client_secret':secret['client_secret'],
'refresh_token':creds['refresh_token'],
'grant_type':'refresh_token'}
headers = {'Content-type':'application/x-www-form-urlencoded'}
(resp, content) = self.http.request(refresh_url,
method='POST',
body=urlencode(post_data),
headers=headers)
content = json.loads(content)
creds['access_token'] = content['access_token']
date = datetime.datetime.now() + datetime.timedelta(seconds=content['expires_in'])
creds['token_expiry'] = json.dumps(date.isoformat())
self.writeCredsToDisk(json.dumps(creds))
您可以编写一个类似于此的函数来交换原始授权代码和访问代码,遵循OAuth Playground向您显示的逻辑。