Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> 實戰Android仿人人客戶端之Auth授權認證(整理流程,重構代碼)

實戰Android仿人人客戶端之Auth授權認證(整理流程,重構代碼)

編輯:Android開發實例

      人人授權認證已聊了兩篇了,這篇重點是整理思路和重構代碼(項目開發過程中開發人員經常干的事)。好了不廢話,下面開始聊今天的內容。

一、人人Auth授權認證流程圖:

二、重構代碼:

       1、再次訪問授權頁出現的空白頁,如下圖:

        解決方法,修改WebView組件的請求重定向方法,處理代碼如下:

 

  1. mWebView.setWebViewClient(new WebViewClient() {  
  2.  
  3.           public boolean shouldOverrideUrlLoading(WebView webView, String url) {  
  4.               Log.i(TAG, "shouldOverrideUrlLoading() Redirect URL = " + url);  
  5.  
  6.               if (url.startsWith(Constant.DEFAULT_REDIRECT_URI + "#error=login_denied")) {  
  7.                   AuthActivity.this.onBackPressed();  
  8.               } else if(url.startsWith(Constant.DEFAULT_REDIRECT_URI + "#access_token")) {  
  9.                   String accessToken = url.substring(url.indexOf("=")+1, url.indexOf("&"));  
  10.                   Log.i(TAG, "accessToken = " + accessToken);  
  11.                     
  12.                   // 人人Demo LOG打印: 195789|6.7faefec2274182195287028d00323781.2592000.1367118000-461345584  
  13.                     
  14.                   // 服務器端返回: 195789%7C6.7faefec2274182195287028d00323781.2592000.1367118000-461345584  
  15.  
  16.                   accessToken = accessToken.replace("%7C", "|");  
  17.                   Log.i(TAG, "Success obtain accessToken = " + accessToken);  
  18.                     
  19.                   // 存儲AccessToken  
  20.                   mAuthTokenManager.storeAccessToken(accessToken);  
  21.                     
  22.                   exchangeSessionKey(accessToken);  
  23.               } else {  
  24.                   webView.loadUrl(url);  
  25.               }  
  26.                
  27.               return true;  
  28.           }  
  29.  
  30.           public void onReceivedSslError(WebView view, SslErrorHandler handler, android.net.http.SslError errorCode) {  
  31.               // 在默認情況下,通過loadUrl(String url)方法,可以順利load。  
  32.               // 但是,當load有ssl層的https頁面時,如果這個網站的安全證書在Android無法得到認證,WebView就會變成一個空白頁,  
  33.               // 而並不會像PC浏覽器中那樣跳出一個風險提示框。因此,我們必須針對這種情況進行處理。(這個證書限於2.1版本以上的Android 系統才可以)  
  34.                 
  35.               // 默認的處理方式,WebView變成空白頁  
  36.               // handler.cancel();   
  37.                 
  38.               // 接受證書     
  39.               handler.proceed();  
  40.           }  
  41.  
  42.           @Override 
  43.           public void onReceivedError(WebView view, int errorCode,  
  44.                   String description, String failingUrl) {  
  45.               super.onReceivedError(view, errorCode, description, failingUrl);  
  46.               AuthActivity.this.onBackPressed();  
  47.           }  
  48.  
  49.           public void onPageStarted(WebView view, String url, Bitmap favicon) {  
  50.               Log.i(TAG, "onPageStarted() URL = " + url);  
  51.                 
  52.               // super.onPageStarted(view, url, favicon);  
  53.           }  
  54.  
  55.           public void onPageFinished(WebView view, String url) {  
  56.                 
  57.               Log.i(TAG, "onPageFinished() URL = " + url);  
  58.                 
  59.               // super.onPageFinished(view, url);  
  60.           }  
  61.       });  


      2、將有關認證授權信息提取放到認證信息管理類中,代碼如下:

  1. package com.everyone.android;  
  2.  
  3. import android.content.Context;  
  4. import android.content.SharedPreferences;  
  5. import android.content.SharedPreferences.Editor;  
  6.  
  7. import com.everyone.android.entity.Authorization;  
  8.  
  9. /**  
  10.  * 功能描述:認證授權信息管理類  
  11.  * @author android_ls  
  12.  *  
  13.  */ 
  14. public final class AuthTokenManager {  
  15.  
  16.     private Context mContext;  
  17.     private SharedPreferences mSharedPreferences;  
  18.       
  19.     public AuthTokenManager(Context context){  
  20.         this.mContext = context;  
  21.         mSharedPreferences = mContext.getSharedPreferences("auth_config", Context.MODE_PRIVATE);  
  22.     }  
  23.       
  24.     /**  
  25.      * 獲取accessToken  
  26.      * @return  
  27.      */ 
  28.     public String getAccessToken() {  
  29.         String accessToken = mSharedPreferences.getString("oauth_token", null);  
  30.         if (accessToken == null) {  
  31.             return null;  
  32.         }  
  33.           
  34.         long createTime = mSharedPreferences.getLong("create_oauth_token_time", 0);  
  35.         long life = Long.parseLong(accessToken.split("\\.")[2]) * 1000;  
  36.         long currenct = System.currentTimeMillis();  
  37.         long oneHour = 1000 * 60 * 60;  
  38.         if ((createTime + life) < (currenct - oneHour)) {  
  39.             Editor editor = mSharedPreferences.edit();  
  40.             editor.clear();  
  41.             editor.commit();  
  42.             return null;  
  43.         }  
  44.         return accessToken;  
  45.     }  
  46.       
  47.     /**  
  48.      * 存儲accessToken,  
  49.      * @param accessToken  
  50.      */ 
  51.     public void storeAccessToken(String accessToken) {  
  52.         Editor editor = mSharedPreferences.edit();  
  53.         if (accessToken != null) {  
  54.             editor.putString("oauth_token", accessToken);  
  55.             editor.putLong("create_oauth_token_time", System.currentTimeMillis());  
  56.         } else {  
  57.             editor.clear();  
  58.         }  
  59.         editor.commit();  
  60.     }  
  61.       
  62.     /**  
  63.      * 在本地存儲Authorization  
  64.      * @param auth  
  65.      */ 
  66.     public void save(Authorization auth){  
  67.         Editor editor = mSharedPreferences.edit();  
  68.         editor.putString("session_key", auth.getSessionKey());  
  69.         editor.putString("session_secret", auth.getSessionSecret());  
  70.         editor.putLong("expires_in", auth.getExpiresIn());  
  71.         editor.putLong("create_session_time", auth.getCreateSessionTime());  
  72.         // editor.putString("oauth_token", auth.getOauthToken());  
  73.         editor.putLong("userId", auth.getUserId());  
  74.         editor.commit();  
  75.     }  
  76.       
  77.     /**  
  78.      * 從SharedPreference中讀入SessionKey  
  79.      */ 
  80.     private Authorization getAuthBySharedPre() {  
  81.         // String oauthToken = mSharedPreferences.getString("oauth_token", null);  
  82.         String sessionKey = mSharedPreferences.getString("session_key", null);  
  83.         String sessionSecret = mSharedPreferences.getString("session_secret", null);  
  84.         long userId = mSharedPreferences.getLong("userId", 0);  
  85.         long expires = mSharedPreferences.getLong("expires_in", 0);   
  86.         long createTime = mSharedPreferences.getLong("create_session_time", 0);  
  87.         long expireTime = createTime + expires;  
  88.           
  89.         Authorization auth = new Authorization();  
  90.         // auth.setOauthToken(oauthToken);  
  91.         auth.setSessionKey(sessionKey);  
  92.         auth.setSessionSecret(sessionSecret);  
  93.         auth.setCreateSessionTime(createTime);  
  94.         auth.setExpiresIn(expireTime);  
  95.         auth.setUserId(userId);  
  96.         return auth;  
  97.     }  
  98.       
  99.     /**  
  100.      * 檢測當前session是否有效  
  101.      * @return   
  102.      *      true - session 有效  
  103.      *      false - session 無效  
  104.      */ 
  105.     public boolean isSessionValid() {  
  106.         Authorization auth = getAuthBySharedPre();  
  107.         long current = System.currentTimeMillis();  
  108.         if(auth.getSessionKey() != null && auth.getSessionSecret() != null   
  109.                 && current < auth.getExpiresIn()) {  
  110.            return true;  
  111.         }  
  112.           
  113.         // sessioin 已過期,刪除SharedPreference中存儲的SessionKey信息  
  114.         Editor editor = mSharedPreferences.edit();  
  115.         editor.clear();  
  116.         editor.commit();  
  117.         return false;  
  118.     }  
  119.       
  120. }  
  121.  

3、將服務器端返回的授權認證JSON字符串的解析工作提取

  1. package com.everyone.android.parse;  
  2.  
  3. import org.json.JSONException;  
  4. import org.json.JSONObject;  
  5.  
  6. import com.everyone.android.entity.Authorization;  
  7. /**  
  8.  * 功能描述:負責解析Auth認證的JSON字符串  
  9.  * @author android_ls  
  10.  *  
  11.  */ 
  12. public final class AuthParse {  
  13.  
  14.     public static Authorization getAuth(String json) throws JSONException {  
  15.         JSONObject jsonObject = new JSONObject(json);  
  16.           
  17.         JSONObject jsonRenrenToken = jsonObject.getJSONObject("renren_token");  
  18.         String sessionKey = jsonRenrenToken.getString("session_key");  
  19.         String sessionSecret = jsonRenrenToken.getString("session_secret");  
  20.         long expiresIn = jsonRenrenToken.getLong("expires_in");  
  21.           
  22.         String oauthToken = jsonObject.getString("oauth_token");  
  23.         long userId = jsonObject.getJSONObject("user").getLong("id");  
  24.           
  25.         // 對Session過期時間進行處理,  Session過期時間 = 系統當前的時間 + 服務器端返回的Session過期時間。  
  26.         long createSessionTime = System.currentTimeMillis();  
  27.         expiresIn = createSessionTime + expiresIn*1000; // 服務器端返回的Session過期時間單位為秒,因此需要乘以1000  
  28.           
  29.         Authorization auth = new Authorization();  
  30.         auth.setOauthToken(oauthToken);  
  31.         auth.setSessionKey(sessionKey);  
  32.         auth.setSessionSecret(sessionSecret);  
  33.         auth.setCreateSessionTime(createSessionTime);  
  34.         auth.setExpiresIn(expiresIn);  
  35.         auth.setUserId(userId);  
  36.           
  37.         return auth;  
  38.     }  
  39.       
  40. }  
  41.  

4、授權認證界面的處理:

  1. /**  
  2.    * 通過accessToken換取session_key、session_secret和userId  
  3.    * @param accessToken  
  4.    */ 
  5.   private void exchangeSessionKey(String accessToken) {  
  6.       if (accessToken == null || accessToken.length() < 1) {  
  7.           return;  
  8.       }  
  9.         
  10.       Map<String, String> parameter = new HashMap<String, String>();  
  11.       parameter.put("oauth_token", accessToken);  
  12.       AsyncBaseRequest asyncRequest = new AsyncHttpPost(Constant.SESSION_KEY_URL, parameter,  
  13.               new ParseCallback (){  
  14.  
  15.                   @Override 
  16.                   public Authorization parse(String json) throws JSONException {  
  17.                       Log.i(TAG, "result = " + json);  
  18.                       if(!TextUtils.isEmpty(json)){  
  19.                             
  20.                           // 服務器端返回的JSON字符串:  
  21.                          /*{  
  22.                              "renren_token":  
  23.                              {  
  24.                                  "session_secret":"52e95c7b02abb0a80a4a80116438063a",  
  25.                                  "expires_in":2595334,  
  26.                                  "session_key":"6.8fed55fdfd5c027c2ecb0ac50859f97c.2592000.1367121600-461345584"  
  27.                              },  
  28.                              "oauth_token":"195789|6.8fed55fdfd5c027c2ecb0ac50859f97c.2592000.1367121600-461345584",  
  29.                              "user":  
  30.                              {  
  31.                                  "id":461345584  
  32.                              }  
  33.                           }*/ 
  34.  
  35.                           // 解析JSON  
  36.                           Authorization auth = AuthParse.getAuth(json);  
  37.                           Log.e(TAG, "auth = " + auth.toString());  
  38.  
  39.                           return auth;  
  40.                       }  
  41.                       return null;  
  42.                   }  
  43.             
  44.       },   
  45.       new  ResultCallback(){  
  46.  
  47.           @Override 
  48.           public void onSuccess(final Object result) {  
  49.               if (!(result instanceof Authorization)) {  
  50.                  Log.e(TAG, "網絡請求返回值解析後不是Authorization類型");  
  51.                  return;  
  52.               }  
  53.                 
  54.               // 本地存儲Authorization授權認證數據  
  55.               mAuthTokenManager.save((Authorization)result);  
  56.               mHandler.post(new Runnable() {  
  57.                     
  58.                   @Override 
  59.                   public void run() {  
  60.                       if (mWebView != null) {  
  61.                           mWebView.stopLoading();  
  62.                       }  
  63.                         
  64.                       Intent intent = new Intent(AuthActivity.this, EveryoneActivity.class);  
  65.                       AuthActivity.this.startActivity(intent);       
  66.                       AuthActivity.this.finish();  
  67.                   }  
  68.               });  
  69.           }  
  70.  
  71.           @Override 
  72.           public void onFail(int errorCode) {  
  73.               Log.e(TAG, "網絡請求返回的errorCode = " + errorCode);                  
  74.           }  
  75.             
  76.       });  
  77.         
  78.       mDefaultThreadPool.execute(asyncRequest);  
  79.       mAsyncRequests.add(asyncRequest);  
  80.   }  

5、導引界面添加的處理:

  1. // 檢測accessToken是否有效  
  2.            String accessToken = mAuthTokenManager.getAccessToken();  
  3.            LogUtil.i(TAG, "accessToken = " + accessToken);  
  4.  
  5.            Intent intent = new Intent();  
  6.            if (accessToken == null) {  
  7.                intent.setClass(this, AuthActivity.class);  
  8.                startActivity(intent);  
  9.                return;  
  10.            }  
  11.  
  12.            // 檢測Session是否有效  
  13.            if (mAuthTokenManager.isSessionValid()) {  
  14.                intent.setClass(this, EveryoneActivity.class);  
  15.                startActivity(intent);  
  16.                finish();  
  17.            } else {  
  18.                // accessToken有效,Session失效  
  19.                exchangeSessionKey(accessToken);  
  20.            }  

注:當accessToken有效,Session失效時的處理,與授權界面的通過accessToken換取session_key、session_secret和userId基本一致,就不貼代碼了。

6、Auth信息實體類代碼:

  1. package com.everyone.android.entity;  
  2.  
  3. /**  
  4.  * 功能描述:Auth信息實體類  
  5.  * @author android_ls  
  6.  *  
  7.  */ 
  8. public class Authorization {  
  9.  
  10.     private String oauthToken; // accessToken  
  11.  
  12.     private long userId; // 當前登錄用戶的uid  
  13.  
  14.     private String sessionKey; // Session key  
  15.  
  16.     private String sessionSecret; // Session Secret  
  17.  
  18.     private long expiresIn; // Session 過期時間  
  19.  
  20.     private long createSessionTime; // 創建時間(從服務器端獲取到時的本地時間)  
  21.  
  22.     public String getOauthToken() {  
  23.         return oauthToken;  
  24.     }  
  25.  
  26.     public void setOauthToken(String oauthToken) {  
  27.         this.oauthToken = oauthToken;  
  28.     }  
  29.  
  30.     public long getUserId() {  
  31.         return userId;  
  32.     }  
  33.  
  34.     public void setUserId(long userId) {  
  35.         this.userId = userId;  
  36.     }  
  37.  
  38.     public String getSessionKey() {  
  39.         return sessionKey;  
  40.     }  
  41.  
  42.     public void setSessionKey(String sessionKey) {  
  43.         this.sessionKey = sessionKey;  
  44.     }  
  45.  
  46.     public String getSessionSecret() {  
  47.         return sessionSecret;  
  48.     }  
  49.  
  50.     public void setSessionSecret(String sessionSecret) {  
  51.         this.sessionSecret = sessionSecret;  
  52.     }  
  53.  
  54.     public long getExpiresIn() {  
  55.         return expiresIn;  
  56.     }  
  57.  
  58.     public void setExpiresIn(long expiresIn) {  
  59.         this.expiresIn = expiresIn;  
  60.     }  
  61.  
  62.     public long getCreateSessionTime() {  
  63.         return createSessionTime;  
  64.     }  
  65.  
  66.     public void setCreateSessionTime(long createSessionTime) {  
  67.         this.createSessionTime = createSessionTime;  
  68.     }  
  69.  
  70.     public String toString() {  
  71.         StringBuilder authResult = new StringBuilder();  
  72.         authResult.append(" oauth_token = ").append(oauthToken);  
  73.         authResult.append("\n session_key = ").append(sessionKey);  
  74.         authResult.append("\n session_secret = ").append(sessionSecret);  
  75.         authResult.append("\n expires_in = ").append(expiresIn);  
  76.         authResult.append("\n userId = ").append(userId);  
  77.  
  78.         return authResult.toString();  
  79.     }  
  80.  
  81. }  
  82.  


有關人人Auth認證的到這裡就聊完了。

 

轉自:http://blog.csdn.net/android_ls/article/details/8748901

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved