Google Play服務和OAuth認證工具

來源:互聯網
上載者:User

Google Play服務在2.2以上裝置的發布在全球範圍內已經完成,所有這些裝置現在在OAuth 2.0下有了新的工具可以使用。下面是一個靈活性方面的例子,這種靈活性可以延伸Google Play服務支援的平台特性。

為什麼是OAuth 2.0

網上已經有很多使用者名稱和密碼了,而且密碼的強度良莠不齊,進一步說,你的裝置肯定能分辨出你是誰,這種情況下,業界一直認為,在缺乏高強度安全密碼 保護的前提下,OAuth 2.0是提供有效安全保障的最佳選擇之一。Google Play服務使需要訪問Google APIs的Android應用也可以使用OAuth 2.0,並且有很好的使用者體驗和安全性。

一般來說,當你的Android應用需要使用Google賬戶去訪問一些東西的時候,你得選擇用這個裝置上的哪個賬戶去訪問,然後必鬚生成一個OAuth2.0的令牌,用這個令牌在基於Http的對話方塊中和資源提供者互動。

如果使用最近為java發布的Google APIs用戶端檔案庫的話,這些任務很大程度上可以自動完成。這裡我們要討論的是你是否直接存取伺服器,比如在發送HTTP get和post請求到一個RESTful 的介面。

 

準備工作

Google Play服務儘管已經開始對外發布,但在發布之後也僅限於2.2及以上版本,大部分機子已經可以使用了,但仍有少量機子不可以。也有可能使用者選擇自己關掉服務。

因為這些原因,在你開始調用前,必須確認Google Play的服務已經安裝,調用isGooglePlayServicesAvailable()可以去確認,如何處理返回結果,在ConnectionResult這個類中有描述。

 

選擇一個賬戶

這不是也永遠不會是複雜困難的事,這兒有許多線上的例子,可以從Android賬戶管理器獲得賬戶和顯示許多種挑選清單。問題是它們有自己的外觀介面和一些類似的東西,比如安全問題。使用者有權期待系統上的一致性。

現在你可以使用 AccountPicker.newChooseAccountIntent()這 個方法獲得一個Intent,將其傳給startActivityForResult()會啟動一個標準的良好的使用者體驗介面,如果使用者願意的話會返回給 你一個賬戶。有兩點要注意:第一,當使用這些APIs時,需要使用一個Google賬戶(AccountManager可以處理多個賬戶),所以指定 GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE的值作為 allowableAccountTypes參數的值。第二,你不需要一個android.accounts.Account對象,只需要email地址就可以,它可以唯一確定一個google賬戶。

 

擷取Token

你能在一次調用中提供多個用空格分開的scop這裡只需要調用一個方法:GoogleAuthUtil.getToken(), 它需要3個參數:Context,email地址,和另一個叫著scope的字串變數。每一個和oauth2.0對話的資訊源需要公布它使用的域 (scope),比如,訪問Google+的api,需要的scope是e,能得到一個可以訪問所有那些scope的令牌(token)。下面就是很典型 的代碼:

View Code

1 private final static String G_PLUS_SCOPE="oauth2:https://www.googleapis.com/auth/plus.me";2  3 private final static String USERINFO_SCOPE =  "https://www.googleapis.com/auth/userinfo.profile";4  5 private final static String SCOPES = G_PLUS_SCOPE + " " + USERINFO_SCOPE;

在理想的情況下,getToken()將會是同步的,但有3件事會讓其變得不那麼簡單:

  1. 應用第一次請求token訪問資源時,系統會和使用者互動,詢問使用者是否允許。
  2. 每次請求token時,系統會和同一個後台伺服器有網路會話。
  3. 處理請求的裝置可能會過載而不能立馬給你token,它不會讓你等或者告訴你請求失敗,而會告知你先離開一會兒再回來。

顯然,你絕對不能在UI線程中調用getToken(),因為那會導致不可預知的延遲。

當你調用getToken()時,會發生以下的事情:

如果成功返回token,那說明各個步驟都是對的,後台認為認證是成功的,接著你處理和使用token就可以了。

拋出UserRecoverableAuthException異常意味著你需要和使用者互動,很可能是要求使用者使用賬戶進行認證。異常有一個getIntent()方法,你可以將其傳回值傳給startActivityForResult()來搞定。當然你需要注意onActivityResult()是否ok。

拋出IOException時,說明證明伺服器很忙,後者有網路異常(在行動裝置上這個情況經常出現)。你不應該馬上就放棄,因為再試一次可能就好了。換句話說,如果你立馬返回並再次向伺服器提出請求,結果不見得好。所以你需要等一下。最好的處理辦法是指數退避模式。

 拋出GoogleAuthException,意味著認證無法通過,你該禮貌地讓你的使用者冷靜下來。如果請求的scope非法或者email地址對應的賬戶在當前裝置上不存在的話就會發生這種異常。

下面是一些範例程式碼:

View Code

 1 try { 2   // if this returns, the OAuth framework thinks the token should be usable 3   String token = GoogleAuthUtil.getToken(this, mRequest.email(), 4   mRequest.scope()); 5   response = doGet(token, this); 6   7 }catch (UserRecoverableAuthException userAuthEx) { 8   // This means that the app hasn't been authorized by the user for access 9   // to the scope, so we're going to have to fire off the (provided) Intent10   // to arrange for that. But we only want to do this once. Multiple11   // attempts probably mean the user said no.12   if (!mSecondTry) {13     startActivityForResult(userAuthEx.getIntent(), REQUEST_CODE);14     response = null;15   } else {16     response = new Response(-1, null, "Multiple approval attempts");17   }18  19 }catch (IOException ioEx) {20   // Something is stressed out; the auth servers are by definition21   //  high-traffic and you can't count on 100% success. But it would be22   //  bad to retry instantly, so back off23   if (backoff.shouldRetry()) {24     backoff.backoff();25     response = authenticateAndGo(backoff);26   } else {27     response = new Response(-1, null, "No response from authorization server.");28   }29 }catch (GoogleAuthException fatalAuthEx)  {30   Log.d(TAG, "Fatal Authorization Exception");31   response = new Response(-1, null, "Fatal authorization exception: " +32   fatalAuthEx.getLocalizedMessage());33 }

這是一個我已經提交到code.google.com上的一個用AuthorizedActivity類實現了的樣本庫。我們 覺得這種認證行為將會是不同應用的特定行為,所以這個AuthorizedActivity類不見得對每個人都有用,但它是基於Apach2許可證,你可 以在你需要的地方隨便用。它已作為一個工程建立了起來,這裡有一個叫做G+ Snowflake的應用,它用那個建好的工程取得了許多你在google+上的提交的東西。這個應用在google play上有,源碼也線上上。

註冊你的應用

大部分進行oauth2.0認證的伺服器都要你進行app註冊,當然google的也不例外。訪問 Google APIs Console, 建立一個工程,把你要訪問的apis從服務菜單中揀出來,然後點擊訪問API的標籤進行註冊。輸入你應用的報名,即在 AndroidManifest.xml中package屬性對應的值,另外需要你應用的SHA1碼。任何在google play 發布過應用的人都知道秘鑰和簽名。但在這之前你會得到一個debug版本的應用,進行這種認證的工具在~/.android /debug.keystore,密碼是android。幸運的是,你的電腦很可能已經裝了keytool這個程式,你能用它來產生你的簽名,對於 debug版本,產生簽名的命令是:

keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore -v -list
這就能產生SHA1簽名,很容易剪下粘貼滴哦。

這方法可能讓人覺得有點陳舊,但卻值得這麼做,因為戲法就是這麼發生的。當你的應用被註冊過,然後你產生一個token並將其發送給服務提供者,服
務提供者通過google檢測token是否正確,token是google發布了的,並且google提供給你應用的包名。之前你們做過這件事的傢伙們
可能想要知道Client IDs和API Keys了,但在這種機制下,你們並不需要它們。

 

使用你的Token

假設你已經註冊過你的應用並調用GoogleAuthUtil.getToken()得到了一個token,假如它就是“MissassaugaParnassus42”。然後你需要做的是,當你向服務提供者發送一個HTTP請求時,包括一個像這樣的HTTP要求標頭:

然後你的HTTP GETs和POSTs開始工作了,你應該調用GoogleAuthUtil.getToken()在每次 GETs 或者 POSTs請求前獲得一個token。在恰當的時候快取資料還有處理token的到期和重新整理,這些事情都不用你操心的。

再說一遍,如我上面說的,如果你用著為java而存在的google apis用戶端很舒服,它將會為你處理所有用戶端的事情,你需要做的就是去註冊一下而已。

另外,在這裡會有一些編碼投入,但回報是巨大的:安全性,認證通過,已授權,擁有良好使用者體驗的服務訪問。


英文原文:Google Data    編譯:ImportNew - 牛秦勇

譯文地址: http://www.importnew.com/949.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.