日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

App Engine中的Google Services身份验证,第1部分

發布時間:2023/12/3 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 App Engine中的Google Services身份验证,第1部分 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這篇文章將說明如何構建一個簡單的Google App Engine(GAE)Java應用程序,該應用程序可針對Google進行身份驗證,并利用Google的OAuth授權訪問Google的API服務(例如Google Docs)。 此外,在Google已經提供的一些示例的基礎上,還將說明如何使用App Engine 數據存儲區和Objectify持久化數據。

項目源代碼

這篇文章背后的動機是,我很難找到以前將這些技術真正聯系在一起的任何示例。 然而,這些技術確實代表了許多想要利用大量Google API服務的Web應用程序的基礎。
為了簡單起見,該演示僅允許用戶通過Google域登錄; 授權訪問用戶的Google文檔服務; 并顯示用戶的Google Docs Word和電子表格文檔的列表。 在本教程中,我會對讀者的專業知識做出一些假設,例如對Java的深入了解。
流程概述

在我們直接進入教程/演示之前,讓我們簡要介紹一下導航流程。

盡管它看起來很復雜,但是主要流程可以總結為:

  • 用戶請求訪問listFiles.jsp(實際上可以使用任何JSP頁面)。
  • 檢查用戶是否已登錄Google。 如果不是,它們將被重定向到Google登錄頁面-登錄后,它們將返回。
  • 然后進行檢查以確定用戶是否存儲在本地數據存儲中。 如果沒有,則將用戶與用戶的Google域電子郵件地址一起添加。
  • 接下來,我們檢查用戶是否已向Google Docs API服務授予OAuth憑據。 如果不是,則啟動OAuth身份驗證過程。 授予OAuth憑據后,它們將存儲在本地用戶表中(因此我們不必在每次用戶嘗試訪問服務時都詢問)。
  • 最后,顯示Google文檔電子表格或Word文檔的列表。
  • 可以使用相同的方法訪問其他Google服務,例如YouTube(例如,您可以顯示用戶喜歡的視頻的列表)。

    環境設定

    對于本教程,我使用以下內容:

    • Eclipse Indigo Service Release 2以及適用于Eclipse的Google插件(請參閱設置說明 )。
    • Google GData Java SDK Eclipse插件版本1.47.1(請參閱設置說明 )。
    • Google App Engine 1.6.5版。 早期版本存在一些問題,因此我建議確保您正在使用它。 它應該作為Eclipse的Google插件的一部分自動安裝。
    • Objectify版本3.1。 所需的庫已安裝在項目的war / WEB-INF / lib目錄中。

    將項目導入Eclipse之后,您的構建路徑應類似于:

    App Engine設置應類似于:

    您將需要設置自己的GAE應用程序,并指定自己的應用程序ID(請參閱Google GAE開發人員文檔 )。
    描述如何使用OAuth訪問谷歌API服務我見過的最好的教程可以找到這里 。 我發現最令人困惑的方面之一是如何獲取放置OAuth請求時所需的必要的消費者密鑰和消費者秘密值。 我完成此操作的方式是:

  • 使用GAE管理控制臺創建GAE應用程序。 您將需要創建自己的應用程序ID(只是您的Web應用程序的名稱)。 有了它,您將在上面顯示的Eclipse App Engine設置面板中更新您的應用程序ID。
  • 為該應用程序創建一個新的域。 例如,由于我的應用程序ID在上面指定為“ tennis-coachrx”,因此我將目標URL路徑前綴配置為:http://tennis-coachrx.appspot.com/authSub。 您將看到我們如何配置該Servlet以便很快接收憑證。
  • 要完成域名注冊,Google將為您提供可以上傳HTML文件。 將該文件的根路徑包括在/ src / war目錄下,然后將應用程序上載到GAE。 這樣,當Google運行檢查時,該文件將存在并會生成必要的消費者憑證。 這是設置完成后的屏幕截圖:
  • 擁有OAuth使用者密鑰和OAuth使用者密鑰之后 ,您將替換com.zazarie.shared.Constant文件中的以下值:
    最后的靜態字符串CONSUMER_KEY =''; 最后的靜態字符串CONSUMER_SECRET =''; 哇,這似乎是很多工作! 但是,這是一次性交易,您不必再次大驚小怪。

    代碼演練

    既然我們已經完成了OAuth的配置/設置,那么我們就可以深入研究代碼了。 讓我們從查看戰爭目錄的結構開始,您的Web資產位于該目錄中:

    listFiles.jsp是您首次進入Web應用程序時顯示的默認JSP頁面。 現在讓我們看一下web.xml文件,看看如何配置它,以及對所有內容都至關重要的servlet過濾器。

    <?xml version='1.0' encoding='UTF-8'?><web-app xmlns:xsi='http:www.w3.org2001XMLSchema-instance'xsi:schemaLocation='http:java.sun.comxmlnsjavaee http:java.sun.comxmlnsjavaeeweb-app_2_5.xsd'version='2.5' xmlns='http:java.sun.comxmlnsjavaee'><!-- Filters --><filter><filter-name>AuthorizationFilter<filter-name><filter-class>com.zazarie.server.servlet.filter.AuthorizationFilter<filter-class><filter><filter-mapping><filter-name>AuthorizationFilter<filter-name><url-pattern>html*<url-pattern><filter-mapping><!-- Servlets --><servlet><servlet-name>Step2<servlet-name><servlet-class>com.zazarie.server.servlet.RequestTokenCallbackServlet<servlet-class><servlet><servlet-mapping><servlet-name>Step2<servlet-name><url-pattern>authSub<url-pattern><servlet-mapping><!-- Default page to serve --><welcome-file-list><welcome-file>htmllistFiles.jsp<welcome-file><welcome-file-list><web-app>

    每當請求位于html目錄中的JSP文件時,就會調用稱為AuthorizationFilter的servlet過濾器。 我們將在稍后介紹的過濾器負責確保用戶已登錄Google,如果是,則確保已為該用戶授予OAuth憑據(即,它將啟動OAuth認證過程(如果需要)。

    步驟2的Servlet名稱代表已授予OAuth憑據時Google調用的Servlet-將其視為回調。 我們將對此進行更詳細的介紹。

    讓我們更詳細地看一下AuthorizationFilter。

    AuthorizationFilter深潛

    doFilter方法是在servlet過濾器中進行工作的地方。 這是實現:

    @Overridepublic void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) res;HttpSession session = request.getSession();LOGGER.info('Invoking Authorization Filter');LOGGER.info('Destination URL is: ' + request.getRequestURI());if (filterConfig == null)return;get the Google userAppUser appUser = LoginService.login(request, response);if (appUser != null) {session.setAttribute(Constant.AUTH_USER, appUser);}identify if user has an OAuth accessToken - it not, will set in motionoauth procedureif (appUser.getCredentials() == null) {need to save the target URI in session so we can forward to it whenoauth is completedsession.setAttribute(Constant.TARGET_URI, request.getRequestURI());OAuthRequestService.requestOAuth(request, response, session);return;} elsestore DocService in the session so it can be reusedsession.setAttribute(Constant.DOC_SESSION_ID,LoginService.docServiceFactory(appUser));chain.doFilter(request, response);}

    除了通常的家務管理之外,主要邏輯還從以下幾行開始:

    AppUser appUser = LoginService.login(request,response);

    稍后我們將看到,LoginService負責將用戶登錄到Google,并在本地BigTable數據存儲區中創建用戶。 通過將用戶存儲在本地,我們可以存儲用戶的OAuth憑據,從而無需用戶每次訪問受限制/過濾的頁面時都必須授予權限。
    LoginService返回用戶(AppUser對象)后,我們將該用戶對象存儲到會話中(注意:要啟用會話,必須在appengine-web.xml文件中將session-enabled設置為:)
    session.setAttribute(Constant.AUTH_USER,appUser);

    然后,我們檢查OAuth憑據是否與該用戶相關聯:

    如果(appUser.getCredentials()== null){

    session.setAttribute(Constant.TARGET_URI,request.getRequestURI());

    OAuthRequestService.requestOAuth(請求,響應,會話);
    返回;
    }其他 session.setAttribute(Constant.DOC_SESSION_ID,LoginService.docServiceFactory(appUser));

    如果getCredentials()返回null,則尚未為用戶分配OAuth憑據。 這意味著OAuth流程需要啟動。 由于此過程分為兩步,即將請求發布到Google,然后通過回調(上面提到的Step2 servlet)檢索結果,因此我們需要存儲目標URL,以便一旦授權后就可以將用戶重定向到該URL。處理完成。 這是通過使用setAttribute方法將請求的URL存儲到會話中來完成的。

    然后,我們通過調用OAuthRequestService.requestOAuth()方法開始OAuth流程(詳細信息將在下面討論)。

    如果getCredentials()返回一個非null值,則表明我們已經從數據存儲區中的本地AppUser條目中獲取了用戶的OAuth憑據,我們只需將其添加到會話中,以便以后使用。

    LoginService深入研究

    LoginService類有一個稱為login的主要方法,其后是一堆JPA幫助器方法,用于保存或更新數據存儲區中的本地用戶。 我們將重點放在login()上,因為這是大多數業務邏輯所在的位置。

    public static AppUser login(HttpServletRequest req, HttpServletResponse res) {LOGGER.setLevel(Constant.LOG_LEVEL);LOGGER.info('Initializing LoginService');String URI = req.getRequestURI();UserService userService = UserServiceFactory.getUserService();User user = userService.getCurrentUser();if (user != null) {LOGGER.info('User id is: '' + userService.getCurrentUser().getUserId()+ ''');String userEmail = userService.getCurrentUser().getEmail();AppUser appUser = (AppUser) req.getSession().getAttribute(Constant.AUTH_USER);if (appUser == null) {LOGGER.info('appUser not found in session');see if it is a new userappUser = findUser(userEmail);if (appUser == null) {LOGGER.info('User not found in datastore...creating');appUser = addUser(userEmail);} else {LOGGER.info('User found in datastore...updating');appUser = updateUserTimeStamp(appUser);}} else {appUser = updateUserTimeStamp(appUser);}return appUser;} else {LOGGER.info('Redirecting user to login page');try {res.sendRedirect(userService.createLoginURL(URI));} catch (IOException e) {e.printStackTrace();}}return null;}

    我們要做的第一件事是使用Google UserService類確定用戶是否登錄到Google:

    UserService userService = UserServiceFactory.getUserService();

    用戶用戶= userService.getCurrentUser();

    如果Google的調用返回的User對象為null,則不會登錄該用戶,并使用以下命令將其重定向到登錄頁面:

    res.sendRedirect(userService.createLoginURL(URI));

    如果用戶已登錄(即不為null),則下一步是確定該用戶是否存在于本地數據存儲中。 這是通過使用appUser = findUser(userEmail)查找用戶及其登錄的Google電子郵件地址來完成的。 由于JPA / Objectify并不是本教程的主要討論點,因此我將不介紹該方法的工作原理。 但是, Objectify網站上有一些很棒的教程/文檔。

    如果用戶不在本地,則使用Google的電子郵件地址填充該對象,并使用appUser = addUser(userEmail)創建該對象。 如果用戶確實存在,我們僅出于登錄目的而更新登錄時間戳。

    OAuthRequestService深入研究
    您可能會回憶起,在本地設置了用戶之后,AuthorizationFilter便會檢查該用戶是否已授予OAuth憑據。 如果不是,則調用OAuthRequestService.requestOAuth()方法。 如下圖所示:

    public static void requestOAuth(HttpServletRequest req,HttpServletResponse res, HttpSession session) {LOGGER.setLevel(Constant.LOG_LEVEL);LOGGER.info('Initializing OAuthRequestService');GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();oauthParameters.setOAuthConsumerKey(Constant.CONSUMER_KEY);oauthParameters.setOAuthConsumerSecret(Constant.CONSUMER_SECRET);Set the scope.oauthParameters.setScope(Constant.GOOGLE_RESOURCE);Sets the callback URL.oauthParameters.setOAuthCallback(Constant.OATH_CALLBACK);GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper(new OAuthHmacSha1Signer());try {Request is still unauthorized at this pointoauthHelper.getUnauthorizedRequestToken(oauthParameters);Generate the authorization URLString approvalPageUrl = oauthHelper.createUserAuthorizationUrl(oauthParameters);session.setAttribute(Constant.SESSION_OAUTH_TOKEN,oauthParameters.getOAuthTokenSecret());LOGGER.info('Session attributes are: '+ session.getAttributeNames().hasMoreElements());res.getWriter().print('<a href='' + approvalPageUrl+ ''>Request token for the Google Documents Scope');} catch (OAuthException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}

    為了簡化OAuth的使用,Google提供了一組我們正在使用的Java幫助器類。 我們需要做的第一件事是設置使用者憑據(獲取這些憑據之前已經討論過):

    GoogleOAuthParameters oauthParameters =新的GoogleOAuthParameters();
    oauthParameters.setOAuthConsumerKey(Constant.CONSUMER_KEY);
    oauthParameters.setOAuthConsumerSecret(Constant.CONSUMER_SECRET);

    然后,我們使用以下命令設置OAuth請求的范圍:
    oauthParameters.setScope(Constant.GOOGLE_RESOURCE);

    Constant.GOOGLE_RESOURCE解析為https://docs.google.com/feeds/的位置。 發出OAuth請求時,請指定您試圖獲得訪問權限的資源范圍。 在這種情況下,我們嘗試訪問Google文檔(每個服務的GData API都提供了作用域URL)。 接下來,我們確定希望Google返回答復的位置。

    oauthParameters.setOAuthCallback(Constant.OATH_CALLBACK);

    無論我們是以開發人員模式在本地運行還是部署到Google App Engine,此值都會更改。 在Constant接口中定義值的方法如下:

    //用于在GAE上運行
    //最終靜態字符串OATH_CALLBACK ='http://tennis-coachrx.appspot.com/authSub';

    //用于本地測試
    最后的靜態字符串OATH_CALLBACK ='http://127.0.0.1:8888/authSub';

    然后,使用Google的幫助程序簽署請求時:

    GoogleOAuthHelper oauthHelper =新的GoogleOAuthHelper(新的OAuthHmacSha1Signer());

    然后,我們生成用戶將導航到的URL,以授權對資源的訪問。 這是使用以下方法動態生成的:

    字符串rovalPageUrl = oauthHelper.createUserAuthorizationUrl(oauthParameters);

    最后一步是向用戶提供鏈接,以便他們可以導航到該URL來批準請求。 這是通過構造一些簡單HTML來完成的,這些HTML使用res.getWriter()。print()輸出。

    用戶授予訪問權限后,Google便會調用由URL參數/ authSub標識的servlet,該參數對應于servlet類RequestTokenCallbackServlet。 接下來,我們將對此進行檢查。

    RequestTokenCallbackServlet深入研究

    該servlet使用Google OAuth幫助程序類來生成所需的訪問令牌和秘密訪問令牌,這些訪問令牌和秘密訪問令牌將在隨后對Google API文檔服務的調用中被使用。 這是從Google接收回叫響應的doGet方法:

    public void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {Create an instance of GoogleOAuthParametersGoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();oauthParameters.setOAuthConsumerKey(Constant.CONSUMER_KEY);oauthParameters.setOAuthConsumerSecret(Constant.CONSUMER_SECRET);GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper(new OAuthHmacSha1Signer());String oauthTokenSecret = (String) req.getSession().getAttribute(Constant.SESSION_OAUTH_TOKEN);AppUser appUser = (AppUser) req.getSession().getAttribute(Constant.AUTH_USER);oauthParameters.setOAuthTokenSecret(oauthTokenSecret);oauthHelper.getOAuthParametersFromCallback(req.getQueryString(),oauthParameters);try {String accessToken = oauthHelper.getAccessToken(oauthParameters);String accessTokenSecret = oauthParameters.getOAuthTokenSecret();appUser = LoginService.getById(appUser.getId());appUser = LoginService.updateUserCredentials(appUser,new OauthCredentials(accessToken, accessTokenSecret));req.getSession().setAttribute(Constant.DOC_SESSION_ID,LoginService.docServiceFactory(appUser));RequestDispatcher dispatcher = req.getRequestDispatcher((String) req.getSession().getAttribute(Constant.TARGET_URI));if (dispatcher != null)dispatcher.forward(req, resp);} catch (OAuthException e) {e.printStackTrace();}}

    Google GoogleOAuthHelper用于執行填充我們感興趣的兩個值所需的內務處理任務:
    字符串accessToken = oauthHelper.getAccessToken(oauthParameters);
    字符串accessTokenSecret = oauthParameters.getOAuthTokenSecret();

    獲得這些值之后,我們便從數據存儲區中重新查詢用戶對象,并將這些值保存到AppUser.OauthCredentials子類中:
    appUser = LoginService.getById(appUser.getId());
    appUser = LoginService.updateUserCredentials(appUser, 新的OauthCredentials(accessToken,accessTokenSecret)); req.getSession()。setAttribute(Constant.DOC_SESSION_ID, LoginService.docServiceFactory(appUser));

    此外,您還會看到它們也存儲在會話中,因此當向Google Docs發出API請求時,我們可以隨時使用它們。

    現在我們有了所需的一切,我們只需將用戶重定向到他們最初請求的資源即可:

    RequestDispatcher調度程序= req.getRequestDispatcher((String)req
    .getSession()。getAttribute(Constant.TARGET_URI));
    dispatcher.forward(req,resp);

    現在,當他們訪問列出他們的文檔的JSP頁面時,一切都會正常!

    這是最終產品的截屏演示:

    希望您喜歡本教程和演示-期待您的評論!

    繼續本教程的第二部分 。

    參考:來自Jeff's SOA Ruminations博客的JCG合作伙伴 Jeff Davis 對Google App Engine中的Google Services進行身份驗證 。


    翻譯自: https://www.javacodegeeks.com/2012/06/google-services-authentication-in-app.html

    總結

    以上是生活随笔為你收集整理的App Engine中的Google Services身份验证,第1部分的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。