转载请标明出处:http://blog.csdn.net/android_ls/article/details/8748901

声明:关于仿人人项目,我是边看人人官方提供的API,边思考,整理好思路,就开始编写代码。有些地方考虑的不是很全面,大家在阅读的时候,对某些细节的处理,若有什么好的处理方式,欢迎交流。(请注意交流时的用词,文明沟通,谢谢。)

人人授权认证已聊了两篇了,这篇重点是整理思路和重构代码(项目开发过程中开发人员经常干的事)。好了不废话,下面开始聊今天的内容。

一、人人Auth授权认证流程图:

二、重构代码:

1、再次访问授权页出现的空白页,如下图:

解决方法,修改WebView组件的请求重定向方法,处理代码如下:

  mWebView.setWebViewClient(new WebViewClient() {public boolean shouldOverrideUrlLoading(WebView webView, String url) {Log.i(TAG, "shouldOverrideUrlLoading() Redirect URL = " + url);if (url.startsWith(Constant.DEFAULT_REDIRECT_URI + "#error=login_denied")) {AuthActivity.this.onBackPressed();} else if(url.startsWith(Constant.DEFAULT_REDIRECT_URI + "#access_token")) {String accessToken = url.substring(url.indexOf("=")+1, url.indexOf("&"));Log.i(TAG, "accessToken = " + accessToken);// 人人Demo LOG打印: 195789|6.7faefec2274182195287028d00323781.2592000.1367118000-461345584// 服务器端返回: 195789%7C6.7faefec2274182195287028d00323781.2592000.1367118000-461345584accessToken = accessToken.replace("%7C", "|");Log.i(TAG, "Success obtain accessToken = " + accessToken);// 存储AccessTokenmAuthTokenManager.storeAccessToken(accessToken);exchangeSessionKey(accessToken);} else {webView.loadUrl(url);}return true;}public void onReceivedSslError(WebView view, SslErrorHandler handler, android.net.http.SslError errorCode) {// 在默认情况下,通过loadUrl(String url)方法,可以顺利load。// 但是,当load有ssl层的https页面时,如果这个网站的安全证书在Android无法得到认证,WebView就会变成一个空白页,// 而并不会像PC浏览器中那样跳出一个风险提示框。因此,我们必须针对这种情况进行处理。(这个证书限于2.1版本以上的Android 系统才可以)// 默认的处理方式,WebView变成空白页// handler.cancel(); // 接受证书   handler.proceed();}@Overridepublic void onReceivedError(WebView view, int errorCode,String description, String failingUrl) {super.onReceivedError(view, errorCode, description, failingUrl);AuthActivity.this.onBackPressed();}public void onPageStarted(WebView view, String url, Bitmap favicon) {Log.i(TAG, "onPageStarted() URL = " + url);// super.onPageStarted(view, url, favicon);}public void onPageFinished(WebView view, String url) {Log.i(TAG, "onPageFinished() URL = " + url);// super.onPageFinished(view, url);}});

2、将有关认证授权信息提取放到认证信息管理类中,代码如下:

package com.everyone.android;import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;import com.everyone.android.entity.Authorization;/*** 功能描述:认证授权信息管理类* @author android_ls**/
public final class AuthTokenManager {private Context mContext;private SharedPreferences mSharedPreferences;public AuthTokenManager(Context context){this.mContext = context;mSharedPreferences = mContext.getSharedPreferences("auth_config", Context.MODE_PRIVATE);}/*** 获取accessToken* @return*/public String getAccessToken() {String accessToken = mSharedPreferences.getString("oauth_token", null);if (accessToken == null) {return null;}long createTime = mSharedPreferences.getLong("create_oauth_token_time", 0);long life = Long.parseLong(accessToken.split("\\.")[2]) * 1000;long currenct = System.currentTimeMillis();long oneHour = 1000 * 60 * 60;if ((createTime + life) < (currenct - oneHour)) {Editor editor = mSharedPreferences.edit();editor.clear();editor.commit();return null;}return accessToken;}/*** 存储accessToken,* @param accessToken*/public void storeAccessToken(String accessToken) {Editor editor = mSharedPreferences.edit();if (accessToken != null) {editor.putString("oauth_token", accessToken);editor.putLong("create_oauth_token_time", System.currentTimeMillis());} else {editor.clear();}editor.commit();}/*** 在本地存储Authorization* @param auth*/public void save(Authorization auth){Editor editor = mSharedPreferences.edit();editor.putString("session_key", auth.getSessionKey());editor.putString("session_secret", auth.getSessionSecret());editor.putLong("expires_in", auth.getExpiresIn());editor.putLong("create_session_time", auth.getCreateSessionTime());// editor.putString("oauth_token", auth.getOauthToken());editor.putLong("userId", auth.getUserId());editor.commit();}/*** 从SharedPreference中读入SessionKey*/private Authorization getAuthBySharedPre() {// String oauthToken = mSharedPreferences.getString("oauth_token", null);String sessionKey = mSharedPreferences.getString("session_key", null);String sessionSecret = mSharedPreferences.getString("session_secret", null);long userId = mSharedPreferences.getLong("userId", 0);long expires = mSharedPreferences.getLong("expires_in", 0); long createTime = mSharedPreferences.getLong("create_session_time", 0);long expireTime = createTime + expires;Authorization auth = new Authorization();// auth.setOauthToken(oauthToken);auth.setSessionKey(sessionKey);auth.setSessionSecret(sessionSecret);auth.setCreateSessionTime(createTime);auth.setExpiresIn(expireTime);auth.setUserId(userId);return auth;}/*** 检测当前session是否有效* @return *      true - session 有效*      false - session 无效*/public boolean isSessionValid() {Authorization auth = getAuthBySharedPre();long current = System.currentTimeMillis();if(auth.getSessionKey() != null && auth.getSessionSecret() != null && current < auth.getExpiresIn()) {return true;}// sessioin 已过期,删除SharedPreference中存储的SessionKey信息Editor editor = mSharedPreferences.edit();editor.clear();editor.commit();return false;}}

3、将服务器端返回的授权认证JSON字符串的解析工作提取

package com.everyone.android.parse;import org.json.JSONException;
import org.json.JSONObject;import com.everyone.android.entity.Authorization;
/*** 功能描述:负责解析Auth认证的JSON字符串* @author android_ls**/
public final class AuthParse {public static Authorization getAuth(String json) throws JSONException {JSONObject jsonObject = new JSONObject(json);JSONObject jsonRenrenToken = jsonObject.getJSONObject("renren_token");String sessionKey = jsonRenrenToken.getString("session_key");String sessionSecret = jsonRenrenToken.getString("session_secret");long expiresIn = jsonRenrenToken.getLong("expires_in");String oauthToken = jsonObject.getString("oauth_token");long userId = jsonObject.getJSONObject("user").getLong("id");// 对Session过期时间进行处理,  Session过期时间 = 系统当前的时间 + 服务器端返回的Session过期时间。long createSessionTime = System.currentTimeMillis();expiresIn = createSessionTime + expiresIn*1000; // 服务器端返回的Session过期时间单位为秒,因此需要乘以1000Authorization auth = new Authorization();auth.setOauthToken(oauthToken);auth.setSessionKey(sessionKey);auth.setSessionSecret(sessionSecret);auth.setCreateSessionTime(createSessionTime);auth.setExpiresIn(expiresIn);auth.setUserId(userId);return auth;}}

4、授权认证界面的处理:

  /*** 通过accessToken换取session_key、session_secret和userId* @param accessToken*/private void exchangeSessionKey(String accessToken) {if (accessToken == null || accessToken.length() < 1) {return;}Map<String, String> parameter = new HashMap<String, String>();parameter.put("oauth_token", accessToken);AsyncBaseRequest asyncRequest = new AsyncHttpPost(Constant.SESSION_KEY_URL, parameter,new ParseCallback (){@Overridepublic Authorization parse(String json) throws JSONException {Log.i(TAG, "result = " + json);if(!TextUtils.isEmpty(json)){// 服务器端返回的JSON字符串:/*{"renren_token":{"session_secret":"52e95c7b02abb0a80a4a80116438063a","expires_in":2595334,"session_key":"6.8fed55fdfd5c027c2ecb0ac50859f97c.2592000.1367121600-461345584"},"oauth_token":"195789|6.8fed55fdfd5c027c2ecb0ac50859f97c.2592000.1367121600-461345584","user":{"id":461345584}}*/// 解析JSONAuthorization auth = AuthParse.getAuth(json);Log.e(TAG, "auth = " + auth.toString());return auth;}return null;}}, new  ResultCallback(){@Overridepublic void onSuccess(final Object result) {if (!(result instanceof Authorization)) {Log.e(TAG, "网络请求返回值解析后不是Authorization类型");return;}// 本地存储Authorization授权认证数据mAuthTokenManager.save((Authorization)result);mHandler.post(new Runnable() {@Overridepublic void run() {if (mWebView != null) {mWebView.stopLoading();}Intent intent = new Intent(AuthActivity.this, EveryoneActivity.class);AuthActivity.this.startActivity(intent);     AuthActivity.this.finish();}});}@Overridepublic void onFail(int errorCode) {Log.e(TAG, "网络请求返回的errorCode = " + errorCode);                }});mDefaultThreadPool.execute(asyncRequest);mAsyncRequests.add(asyncRequest);}

5、导引界面添加的处理:

 // 检测accessToken是否有效String accessToken = mAuthTokenManager.getAccessToken();LogUtil.i(TAG, "accessToken = " + accessToken);Intent intent = new Intent();if (accessToken == null) {intent.setClass(this, AuthActivity.class);startActivity(intent);return;}// 检测Session是否有效if (mAuthTokenManager.isSessionValid()) {intent.setClass(this, EveryoneActivity.class);startActivity(intent);finish();} else {// accessToken有效,Session失效exchangeSessionKey(accessToken);}

注:当accessToken有效,Session失效时的处理,与授权界面的通过accessToken换取session_key、session_secret和userId基本一致,就不贴代码了。

6、Auth信息实体类代码:

package com.everyone.android.entity;/*** 功能描述:Auth信息实体类* @author android_ls**/
public class Authorization {private String oauthToken; // accessTokenprivate long userId; // 当前登录用户的uidprivate String sessionKey; // Session keyprivate String sessionSecret; // Session Secretprivate long expiresIn; // Session 过期时间private long createSessionTime; // 创建时间(从服务器端获取到时的本地时间)public String getOauthToken() {return oauthToken;}public void setOauthToken(String oauthToken) {this.oauthToken = oauthToken;}public long getUserId() {return userId;}public void setUserId(long userId) {this.userId = userId;}public String getSessionKey() {return sessionKey;}public void setSessionKey(String sessionKey) {this.sessionKey = sessionKey;}public String getSessionSecret() {return sessionSecret;}public void setSessionSecret(String sessionSecret) {this.sessionSecret = sessionSecret;}public long getExpiresIn() {return expiresIn;}public void setExpiresIn(long expiresIn) {this.expiresIn = expiresIn;}public long getCreateSessionTime() {return createSessionTime;}public void setCreateSessionTime(long createSessionTime) {this.createSessionTime = createSessionTime;}public String toString() {StringBuilder authResult = new StringBuilder();authResult.append(" oauth_token = ").append(oauthToken);authResult.append("\n session_key = ").append(sessionKey);authResult.append("\n session_secret = ").append(sessionSecret);authResult.append("\n expires_in = ").append(expiresIn);authResult.append("\n userId = ").append(userId);return authResult.toString();}}

有关人人Auth认证的到这里就聊完了。

Android仿人人客户端(v5.7.1)——Auth授权认证(整理流程,重构代码)相关推荐

  1. Android仿人人客户端(v5.7.1)——项目框架新做的调整描述(项目中基类java源码)...

    转载请标明出处:http://blog.csdn.net/android_ls/article/details/8909068 声明:没看过仿人人android客户端系列博文,前面的相关文章的朋友,请 ...

  2. Android仿人人客户端(v5.7.1)——对从服务器端(网络)获取的图片进行本地双缓存处理(编码实现)...

    转载请标明出处:http://blog.csdn.net/android_ls/article/details/8797740 这篇是基于上一篇Android仿人人客户端(v5.7.1)--对从服务器 ...

  3. Android仿人人客户端(v5.7.1)——通过HTTPS协议的POST方式获取用户的基本信息

    转载请标明出处:http://blog.csdn.net/android_ls/article/details/8770537 一.扩展之前的网络模块 基于Android仿人人客户端(v5.7.1)- ...

  4. Android仿人人客户端(v5.7.1)——采用RelativeLayout做父容器,实现左侧滑动菜单(二)...

    转载请标明出处:http://blog.csdn.net/android_ls/article/details/8758943 上一篇在Android仿人人客户端(v5.7.1)--应用主界面之滑动效 ...

  5. Android仿人人客户端(v5.7.1)——网络模块处理的架构

    转载请标明出处:http://blog.csdn.net/android_ls/article/details/8732427 声明:仿人人项目,所用所有图片资源都来源于官方人人android客户端, ...

  6. Android仿人人客户端(v5.7.1)——采用RelativeLayout做父容器,实现左侧滑动菜单(二)

    转载请标明出处:http://blog.csdn.net/android_ls/article/details/8758943 上一篇在Android仿人人客户端(v5.7.1)--应用主界面之滑动效 ...

  7. Android仿人人客户端(v5.7.1)——新鲜事之下拉列表(过滤项列表)

    转载请标明出处:http://blog.csdn.net/android_ls/article/details/8884335 声明:仿人人项目,所用所有图片资源都来源于其它Android移动应用,编 ...

  8. Android仿人人客户端(v5.7.1)——点击左侧菜单栏中的Item切换视图

    转载请标明出处:http://blog.csdn.net/android_ls/article/details/8765193 在前面几讲中,左侧菜单(左侧面板).满足滑动或点击子View的方式,打开 ...

  9. Android仿人人客户端(v5.7.1)——应用主界面之左侧面板UI实现

    转载请标明出处:http://blog.csdn.net/android_ls/article/details/8749188 声明:仿人人项目,所用所有图片资源都来源于其它Android移动应用,编 ...

最新文章

  1. 中山学院计算机学院家长座谈会,计算机科学与技术学院举办校友座谈会
  2. 【CV中的注意力机制】史上最强ResNet变体--ResNeSt
  3. VisualSVN安装配置与使用
  4. 反思耗时任务异步处理
  5. php单机session消失_Session 失效的原因汇总及解决丢失办法
  6. python运行别人的项目_pycharm实现在虚拟环境中引入别人的项目
  7. 云原生时代业务架构的变革:从单体迈向Serverless
  8. java radio 不可选_在Java Swing中取消选择RadioButtons
  9. 系统架构设计师与系统分析师历年实体分析与解答下载_架构设计的本质
  10. macOS下统计pdf字数
  11. 算法设计与分析:最短路径问题(哈密顿回路+最短路)小学期实践
  12. PRD:腾讯会议APP产品需求文档
  13. 东方计算机学校老师,衡水东方计算机中等专业学校举行校园开放日活动
  14. QT 怎么获取linux本机的IP地址?
  15. mysql小鸭子_可读代码编写炸鸡十一 - 小黄鸭从你的心里游到脑子里
  16. 【服务器数据恢复】多块磁盘离线导致RAIDZ崩溃的数据恢复案例
  17. MacOS 10.15 Catalina 更新系统后无法访问根目录下的/dashu/log
  18. SQL自动备份数据到另一台电脑
  19. 安卓机器人做图软件_绘画机器人andy下载-美图秀秀绘画机器人下载v7.0.0.0 安卓版-西西软件下载...
  20. android手机听广播,RadioTime让你的android也能听收音机

热门文章

  1. 【近万字】分数傅里叶变换课程学习笔记
  2. python generator类型_python生成器(Generator)
  3. linux中安装pip镜像怎么设置_linux服务器怎么安装pip?
  4. 认真学习系列:数据结构与算法——慕课网笔记
  5. 如何使用windows自带的远程协助
  6. servlet对java的重要性_浅谈Servlet技术中的Listener起到的作用
  7. Java高并发编程详解-代码在本地
  8. 【月报】滨哥教我的宝贵经验
  9. 《Docker技术从入门到实践》第3,4,5章(三大概念)
  10. Hibenate连接mysql错误_hibernate连接数据库问题,注意是表名的大小写