衡水做网站的公司网络服务器忙
web/
2025/9/27 7:45:36/
文章来源:
衡水做网站的公司,网络服务器忙,公司域名备案流程,建设网站后期人员薪酬app engine在本教程的第一部分中#xff0c; 我介绍了如何使用OAuth进行Google API服务的访问/身份验证。 不幸的是#xff0c;正如我稍后发现的那样#xff0c;我使用的方法是OAuth 1.0#xff0c;显然现在Google正式弃用了OAuth 1.0#xff0c;改用OAuth 2.0版本。 显然… app engine 在本教程的第一部分中 我介绍了如何使用OAuth进行Google API服务的访问/身份验证。 不幸的是正如我稍后发现的那样我使用的方法是OAuth 1.0显然现在Google正式弃用了OAuth 1.0改用OAuth 2.0版本。 显然发现这一点让我有些沮丧并保证我将创建一个新博客条目其中包含有关如何使用2.0的说明。 好消息是有了2.0支持Google添加了一些附加的帮助程序类这些类使事情变得更加容易特别是如果您使用的是Google App Engine这正是我在本教程中使用的。 Google Developers网站现在对如何设置OAuth 2.0进行了很好的描述 。 但是事实证明如何配置一个真实的示例如何完成它是一个挑战因此我想记录下我学到的东西。 教程场景在上一个教程中我创建的项目说明了如何访问用户的Google Docs文件列表。 在本教程中我做了一些改动而是使用YouTube的API来显示用户喜欢的视频的列表。 访问用户的收藏夹确实需要使用OAuth进行身份验证因此这是一个很好的测试。 入门 可在此处找到本教程的Eclipse项目。 您必须做的第一件事是遵循Google官方文档中概述的有关使用OAuth 2.0的步骤。 由于我正在创建一个Web应用程序因此您将需要遵循这些文档中名为“ Web服务器应用程序”的部分。 此外我之前讨论的用于设置Google App Engine的步骤仍然很重要因此我将直接进入代码并跳过这些设置步骤。 注意可以在这里找到Eclipse项目-我再次选择不使用Maven以便使那些没有安装Maven或在Maven中了解很多的人变得更简单。 应用程序流程非常简单假设是首次使用用户 用户访问Web应用程序时假设您正在使用GAE开发人员模拟器在http// localhost8888在本地运行该Web应用程序则他们必须首先使用其gmail或Google域帐户登录到Google。 登录后用户将被重定向到一个简单的JSP页面该页面具有指向其YouTube最喜欢的视频的链接。 当点击链接时servlet将启动OAuth流程以获取对其YouTube帐户的访问权限。 此过程的第一部分将被重定向到Google Page该页面会提示他们是否要授予应用程序访问权限。 假设用户回答是肯定的将显示10个带有链接的收藏夹列表。 如果他们单击链接将加载视频。 这是前3页流程的描述 这是最后两页假设用户单击了给定的链接 尽管此示例特定于YouTube但相同的通用原则适用于访问任何基于Google的云服务例如Google Google DriveDocs等。它们创建此类集成的关键推动因素显然是OAuth因此让我们看看如何该过程有效。 OAuth 2.0处理流程 对于刚开始学习该技术的新开发人员而言使用OAuth可能会有些不知所措。 其背后的主要前提是允许用户有选择地确定他们希望外部应用程序可以访问哪些“私有”资源例如我们正在为本教程开发的资源。 通过使用OAuth用户可以避免与第三方共享其登录凭据而可以简单地向该第三方授予访问其某些信息的权限。 为了实现此功能需要将用户导航到其私人数据所在的源在本例中为YouTube。 然后他们可以允许或拒绝访问请求。 如果他们允许则私有数据YouTube的源将一次性授权码返回给第三方应用程序。 由于每次需要访问权限时用户都必须授予访问权限是一件很麻烦的事情因此可以进行另一次通话将长期使用“一次性使用”授权进行“折衷”。 我们为本教程开发的Web应用程序的总体流程如下所示。 OAuth流程 进行的第一步是确定用户是否已经使用其gmail或Google Domain帐户登录到Google。 尽管不直接与OAuth流程相关联但使用户能够使用其Google帐户登录非常方便而不是要求用户登录您的网站。 这是对Google的第一个标注。 然后一旦登录应用程序将确定用户是否具有授予OAuth权限的本地帐户设置。 如果他们是第一次登录则不会。 在这种情况下将启动OAuth流程。 该过程的第一步是向OAuth提供程序在本例中为Google YouTube指定请求访问的“范围”。 由于Google提供了很多服务因此它们具有很多范围。 您可以使用其OAuth 2.0沙箱轻松确定。 当您启动OAuth流程时会向他们提供您想要访问的范围以及Google为您提供的OAuth客户端凭据这些步骤实际上是支持OAuth的任何提供程序所通用的。 为了我们的目的我们正在寻求访问该用户的YouTube帐户的权限因此Google提供的范围是https//gdata.youtube.com/。 如果最终用户授予对由范围标识的资源的访问权限则Google会将授权码发回给应用程序。 这是在servlet中捕获的。 由于返回的代码只是“一次性”代码因此将其交换为运行时间更长的访问令牌和相关的刷新令牌。 上面的步骤由标题为“请求访问和刷新令牌”的活动/框表示。 一旦有了访问令牌应用程序便可以通过将API调用与令牌一起放置来访问用户的私有数据。 如果一切顺利API将返回结果。 这不是一个可怕的复杂过程它只涉及几个步骤。 让我们看一些具体的实现细节首先从servlet过滤器开始该过滤器确定用户是否已经登录Google和/或已授予OAuth访问权限。 授权过滤器 让我们看一下AuthorizationFilter的前几行要了解如何将其配置为过滤器请参阅web.xml文件。 public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {HttpServletRequest request (HttpServletRequest) req;HttpServletResponse response (HttpServletResponse) res;HttpSession session request.getSession();if not present, add credential store to servlet contextif (session.getServletContext().getAttribute(Constant.GOOG_CREDENTIAL_STORE) null) {LOGGER.fine(Adding credential store to context credentialStore);session.getServletContext().setAttribute(Constant.GOOG_CREDENTIAL_STORE, credentialStore);}if google user isnt in session, add itif (session.getAttribute(Constant.AUTH_USER_ID) null) {LOGGER.fine(Add user to session);UserService userService UserServiceFactory.getUserService();User user userService.getCurrentUser();session.setAttribute(Constant.AUTH_USER_ID, user.getUserId());session.setAttribute(Constant.AUTH_USER_NICKNAME, user.getNickname());if not running on app engine prod, hard-code my email address for testingif (SystemProperty.environment.value() SystemProperty.Environment.Value.Production) {session.setAttribute(Constant.AUTH_USER_EMAIL, user.getEmail());} else {session.setAttribute(Constant.AUTH_USER_EMAIL, jeffdaviscogmail.com);}} 前几行简单地将通用servlet请求和响应转换为它们对应的Http等值-这是必需的因为我们要访问HTTP会话。 下一步是确定Servlet上下文中是否存在CredentialStore。 正如我们将看到的它用于存储用户的凭证因此在后续的servlet中随时可以使用它很方便。 当我们使用以下方法检查会话中是否已经存在该用户时便开始了此事 if (session.getAttribute(Constant.AUTH_USER_ID) null) { 如果没有我们将使用Google的UserService类获取其Google登录凭据。 这是可供GAE用户使用的帮助程序类用于获取用户的Google用户ID电子邮件和昵称。 从UserService获得此信息后我们将在会话中存储一些用户的详细信息。 到目前为止我们还没有对OAuth做任何事情但是在接下来的代码行系列中会有所改变 尝试{ Utils.getActiveCredentialrequestcredentialStore; } catchNoRefreshTokenException e1{ //如果输入了该catch块则需要执行oauth流程 LOGGER.info未找到用户–授权URL为 e1.getAuthorizationUrl; response.sendRedirecte1.getAuthorizationUrl; } 大多数OAuth处理都使用一个称为Utils的帮助程序类。 在这种情况下我们将调用静态方法getActiveCredential。 稍后我们将看到如果以前没有为用户捕获OAuth凭据则此方法将返回NoRefreshTokenException。 作为自定义例外它将返回URL值该URL值用于将用户重定向到Google以寻求OAuth批准。 让我们更详细地了解getActiveCredential方法因为这是管理许多OAuth处理的地方。 public static Credential getActiveCredential(HttpServletRequest request, CredentialStore credentialStore) throws NoRefreshTokenException {String userId (String) request.getSession().getAttribute(Constant.AUTH_USER_ID);Credential credential null;try {if (userId ! null) {credential getStoredCredential(userId, credentialStore);}if ((credential null || credential.getRefreshToken() null) request.getParameter(code) ! null) {credential exchangeCode(request.getParameter(code));LOGGER.fine(Credential access token is: credential.getAccessToken());if (credential ! null) {if (credential.getRefreshToken() ! null) {credentialStore.store(userId, credential);}}}if (credential null || credential.getRefreshToken() null) {String email (String) request.getSession().getAttribute(Constant.AUTH_USER_EMAIL);String authorizationUrl getAuthorizationUrl(email, request);throw new NoRefreshTokenException(authorizationUrl);}} catch (CodeExchangeException e) {e.printStackTrace();} return credential;} 我们要做的第一件事是从会话中获取Google userId如果没有填充则无法做到这一点。 接下来我们尝试使用Utils静态方法getStoredCredential从CredentialStore获取用户的OAuth凭据以相同名称存储在Google类中。 如果找不到该用户的凭据则调用名为getAuthorizationUrl的Utils方法。 如下所示此方法用于构造浏览器重定向到的URL该URL用于提示用户授权访问其私有数据该URL由Google提供因为它将询问用户批准。 private static String getAuthorizationUrl(String emailAddress, HttpServletRequest request) {GoogleAuthorizationCodeRequestUrl urlBuilder null;try {urlBuilder new GoogleAuthorizationCodeRequestUrl(getClientCredential().getWeb().getClientId(),Constant.OATH_CALLBACK,Constant.SCOPES).setAccessType(offline).setApprovalPrompt(force);} catch (IOException e) {TODO Auto-generated catch blocke.printStackTrace();}urlBuilder.set(state, request.getRequestURI());if (emailAddress ! null) {urlBuilder.set(user_id, emailAddress);}return urlBuilder.build();} 如您所见此方法使用的是GoogleAuthorizationCodeRequestUrl类来自Google。 它使用您注册使用OAuth时由Google提供的OAuth客户端凭据来构造HTTP调用巧合的是这些凭据存储在名为client_secrets.json的文件中。其他参数包括OAuth请求的范围和URL如果获得用户的批准该用户将被重定向回。该URL是您在注册Google的OAuth访问时指定的URL 现在如果用户已经授予OAuth访问权限则getActiveCredential方法将改为从CredentialStore获取凭据。 回到接收OAuth凭证结果的URL在本例中为http// localhost8888 / authSub您可能想知道Google如何发布到该内部专用地址 好吧实际上是用户的浏览器发回了结果因此在这种情况下本地主机就可以很好地解决问题。 让我们看一下用于处理此回调的名为OAuth2Callback的servlet有关如何完成authSub的servlet映射的信息请参见web.xml。 public class OAuth2Callback extends HttpServlet {private static final long serialVersionUID 1L;private final static Logger LOGGER Logger.getLogger(OAuth2Callback.class.getName());public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {StringBuffer fullUrlBuf request.getRequestURL();Credential credential null;if (request.getQueryString() ! null) {fullUrlBuf.append(?).append(request.getQueryString());}LOGGER.info(requestURL is: fullUrlBuf);AuthorizationCodeResponseUrl authResponse new AuthorizationCodeResponseUrl(fullUrlBuf.toString());check for user-denied errorif (authResponse.getError() ! null) {LOGGER.info(User-denied access);} else {LOGGER.info(User granted oauth access);String authCode authResponse.getCode();request.getSession().setAttribute(code, authCode);response.sendRedirect(authResponse.getState());}}} 该课程最重要的收获是 AuthorizationCodeResponseUrl authResponse 新的AuthorizationCodeResponseUrlfullUrlBuf.toString; Google提供了AuthorizationCodeResponseUrl类以方便分析OAuth请求的结果。 如果该类的getError方法不为null则表示用户拒绝了该请求。 如果它为null表示用户已批准该请求则使用方法调用getCode来检索一次性授权码。 此代码值放入用户的会话中并且在重定向到用户的目标URL通过过滤器后调用Utils.getActiveCredential时它将使用该授权代码交换长期访问权限并使用电话 凭据 exchangeCodeStringrequest.getSession。getAttributecode; Utils.exchangeCode方法如下所示 public static Credential exchangeCode(String authorizationCode)throws CodeExchangeException {try {GoogleTokenResponse response new GoogleAuthorizationCodeTokenRequest(new NetHttpTransport(), Constant.JSON_FACTORY, Utils.getClientCredential().getWeb().getClientId(), Utils.getClientCredential().getWeb().getClientSecret(),authorizationCode, Constant.OATH_CALLBACK).execute();return Utils.buildEmptyCredential().setFromTokenResponse(response);} catch (IOException e) {e.printStackTrace();throw new CodeExchangeException();}} 此方法还使用称为GoogleAuthorizationCodeTokenRequest的Google类该类用于调用Google以将一次性OAuth授权代码交换为持续时间较长的访问令牌。 现在我们已经终于获得了YouTube API所需的访问令牌我们可以向用户显示其视频收藏夹中的10个。 调用YouTube API服务 有了访问令牌我们现在可以继续向用户显示其收藏夹列表。 为了做到这一点调用了一个名为FavoritesServlet的servlet。 它将调用YouTube API通过Jackson将生成的JSON-C格式解析为一些本地Java类然后将结果发送到JSP页面进行处理。 这是servlet public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {LOGGER.fine(Running FavoritesServlet);Credential credential Utils.getStoredCredential((String) request.getSession().getAttribute(Constant.AUTH_USER_ID), (CredentialStore) request.getSession().getServletContext().getAttribute(Constant.GOOG_CREDENTIAL_STORE));VideoFeed feed null;if the request fails, its likely because access token is expired - well refreshtry {LOGGER.fine(Using access token: credential.getAccessToken());feed YouTube.fetchFavs(credential.getAccessToken());} catch (Exception e) {LOGGER.fine(Refreshing credentials);credential.refreshToken();credential Utils.refreshToken(request, credential);GoogleCredential googleCredential Utils.refreshCredentials(credential);LOGGER.fine(Using refreshed access token: credential.getAccessToken());retry feed YouTube.fetchFavs(credential.getAccessToken());} LOGGER.fine(Video feed results are: feed);request.setAttribute(Constant.VIDEO_FAVS, feed);RequestDispatcher dispatcher getServletContext().getRequestDispatcher(htmllistVids.jsp);dispatcher.forward(request, response); } 由于这篇文章主要是关于OAuth流程的因此我不会过多介绍API调用的放置方式但是最重要的代码行是feed YouTube.fetchFavscredential.getAccessToken; feed是VideoFeed的实例。 如您所见另一个名为YouTube的帮助程序类用于执行繁重的工作。 为了总结我将展示fetchFavs方法。 public static VideoFeed fetchFavs(String accessToken) throws IOException, HttpResponseException {HttpTransport transport new NetHttpTransport();final JsonFactory jsonFactory new JacksonFactory();HttpRequestFactory factory transport.createRequestFactory(new HttpRequestInitializer() {Overridepublic void initialize(HttpRequest request) {set the parserJsonCParser parser new JsonCParser(jsonFactory);request.addParser(parser);set up the Google headersGoogleHeaders headers new GoogleHeaders();headers.setApplicationName(YouTube Favorites1.0);headers.gdataVersion 2;request.setHeaders(headers);}});build the YouTube URLYouTubeUrl url new YouTubeUrl(Constant.GOOGLE_YOUTUBE_FEED);url.maxResults 10;url.access_token accessToken;build the HTTP GET requestHttpRequest request factory.buildGetRequest(url);HttpResponse response request.execute();execute the request and the parse video feedVideoFeed feed response.parseAs(VideoFeed.class);return feed;} 它使用称为HttpRequestFactory的Google类来构造对YouTube的出站HTTP API调用。 由于我们使用的是GAE因此我们只能使用哪些类来发出此类请求。 请注意以下代码行 url.access_token accessToken; 那就是我们使用通过OAuth流程获取的访问令牌的地方。 因此尽管需要花费大量代码才能使OAuth内容正常运行但是一旦安装妥当您就可以准备调用各种Google API服务来进行滚动 参考我们的JCG合作伙伴 Jeff Davis在Jeffs SOA Ruminations博客上提供的Google服务认证第2部分 。 翻译自: https://www.javacodegeeks.com/2012/06/google-services-authentication-in-app_20.htmlapp engine
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/82631.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!