最近在做一个图片分享的APP,为增加用户入口,便于注册,先采用新浪微博作为第三方的入口。 我采用的注册流程如下:
1 btnWeibo.setOnClickListener(new View.OnClickListener() { 2 3 @Override 4 public void onClick(View v) { 5 Intent intent = new Intent(LoginActivity.this, 6 SinaOAuthActivity.class); 7 startActivity(intent); 8 } 9 });
2. 载入认证页面,使用到的微博提供的url功能接口如下
1 public static String SINA_CONSUMER_KEY = "APP KEY"; 2 public static String SINA_CONSUMER_SECRET = "APP SECRET"; 3 public static String ACCESS_TOKEN = ""; 4 public static String UID =""; 5 public static String PREFERENCES_NAME = "PACKET NAME"; //可在AndroidManifest.xml中查看 6 //认证页面url 7 public static String SINA_OAUTH = "https://api.weibo.com/oauth2/authorize?client_id=" 8 + SINA_CONSUMER_KEY 9 + "&response_type=code&redirect_uri=http://www.sina.com" 10 + "&display=mobile"; 11 //获取ACCESS TOKEN 12 public static String SINA_ACCESS_TOKEN = "https://api.weibo.com/oauth2/access_token?client_id=" 13 + SINA_CONSUMER_KEY 14 + "&client_secret=" 15 + SINA_CONSUMER_SECRET 16 + "&grant_type=authorization_code&redirect_uri=http://www.sina.com&code="; 17 //根据UID获取用户详细信息 18 private static String SINA_DETAIL_INFORMATION = "https://api.weibo.com/2/users/show.json?source=" 19 + SINA_CONSUMER_KEY 20 + "&access_token=" 21 + ACCESS_TOKEN 22 + "&uid="+UID;
3. 认证Activity代码如下, 登陆并获取用户信息后,与客户端进行通信,验证该用户(微博用户)是否已在本服务器注册,若已注册,直接登陆;若未注册,跳转至设置密码页面。之后在本地添加用户登录信息,即可免填写用户名密码直接登录。
1 public class SinaOAuthMainActivity extends Activity { 2 public WebView webview; 3 String code = ""; 4 String result =""; 5 Intent intent; 6 public WeiboUser user = new WeiboUser(); 7 public SPreferenceInf spi = new SPreferenceInf(); 8 public static final String WEIBO_USER = "com.cse.myperson.WEIBO_USER"; 9 @Override 10 protected void onCreate(Bundle savedInstanceState) { 11 super.onCreate(savedInstanceState); 12 setContentView(R.layout.sina_oauth_webview); 13 webview = (WebView) this.findViewById(R.id.oauth_webview); 14 webview.getSettings().setJavascriptEnabled(true); 15 webview.setFocusable(true); 16 webview.loadUrl(WeiboConstant.SINA_OAUTH); 17 18 webview.setWebViewClient(new WebViewClient() { 19 @Override 20 public void onPageFinished(WebView view, String url) { 21 new Thread(runnable).start(); 22 Log.i("onPageFinished", url + "网页加载完毕"); 23 super.onPageFinished(view, url); 24 } 25 26 @Override 27 public boolean shouldOverrideUrlLoading(WebView view, String url) { 28 Log.i("shouldOverrideUrlLoading", url); 29 webview.loadUrl(url); 30 return super.shouldOverrideUrlLoading(view, url); 31 } 32 33 // 加载页面 34 @Override 35 public void onPageStarted(WebView view, String url, Bitmap favicon) { 36 Log.e("onPageStarted", url + "开始加载界面"); 37 if (url.startsWith("http://www.sina.com")) { 38 // 取消授权后的界面 39 view.cancelLongPress(); 40 view.stopLoading(); 41 42 // 获取Code 43 Uri uri = Uri.parse(url); 44 code = uri.getQueryParameter("code"); 45 Log.e("code", WeiboConstant.SINA_ACCESS_TOKEN + code); 46 47 try { 48 Thread.sleep(1000); 49 } catch (InterruptedException e) { 50 // TODO Auto-generated catch block 51 e.printStackTrace(); 52 } 53 if (result.startsWith("{\"access_token\":")) { 54 int i = result.indexOf(":"); 55 int j = result.indexOf(","); 56 WeiboConstant.ACCESS_TOKEN = result.substring(i + 2, 57 j - 1); 58 int uidIndex = result.indexOf("uid"); 59 int endIndex = result.length(); 60 WeiboConstant.UID = result.substring(uidIndex+6,endIndex-2); 61 62 Log.e("ACCESS_TOKEN", WeiboConstant.ACCESS_TOKEN); 63 Log.e("UID", WeiboConstant.UID); 64 new Thread(runnable_USER).start(); 65 finish(); 66 } 67 } 68 super.onPageStarted(view, url, favicon); 69 } 70 }); 71 } 72 73 //登陆请求 74 Runnable runnable = new Runnable(){ 75 76 @Override 77 public void run() { 78 // TODO Auto-generated method stub 79 if (code != null) { 80 result = HttpsUtil.HttpsPost( 81 WeiboConstant.SINA_ACCESS_TOKEN + code, ""); 82 Log.e("Https地址", WeiboConstant.SINA_ACCESS_TOKEN + code); 83 Log.e("登录请求结果", result); 84 } 85 } 86 87 }; 88 89 90 //获取个人信息请求 91 Runnable runnable_USER = new Runnable(){ 92 93 @Override 94 public void run() { 95 String url = StaticValue.url+"/register"; 96 97 if (code != null ) { 98 result = HttpsUtil.httpPost( 99 WeiboConstant.freshSinaInf(), ""); 100 if(!result.startsWith("{\"error\":")){ 101 user.adapter(result); 102 user.showAll(); 103 104 } 105 Log.e("请求用户信息Https地址", WeiboConstant.freshSinaInf()); 106 Log.e("用户详细信息", result); 107 } 108 String result = CheckRegister.checkRegisterRequest(url, user.getLoginname()); 109 String[] params; 110 params = result.split(";"); 111 if(params[0].equals("existed")){ 112 SharedPerferenceUtil.writeSP(SinaOAuthActivity.this, 113 user.getLoginname(), params[1]); 114 intent = new Intent(SinaOAuthActivity.this, 115 LoginActivity.class); 116 startActivity(intent); 117 finish(); 118 }else if(params[0].equals("inexist")){ 119 toSetPass(); 120 Toast.makeText(SinaOAuthActivity.this, "认证成功", 121 Toast.LENGTH_LONG).show(); 122 } 123 124 } 125 126 }; 127 128 /** 129 * 跳转至密码设置页面 130 */ 131 public void toSetPass(){ 132 Log.e("from success!!!!!","loginname is "+user.getLoginname() 133 +"username is "+user.getUsername()); 134 intent = new Intent(SinaOAuthActivity.this, 135 SetPasswordActivity.class); 136 Bundle mBundle = new Bundle(); 137 mBundle.putSerializable(WEIBO_USER, user); 138 intent.setAction(WEIBO_USER); 139 intent.putExtras(mBundle); 140 startActivity(intent); 141 } 142 143 }
4. 这里有一个地方需注意,当采用WebView微博登陆后,每次登陆都会在本地保存COOKIEs登陆信息。这也是我在开发中遇到的一个难题,一个用户注册成功后,再次进入,直接提示认证成功。一开始认为是用SharedPreferences将登陆信息保存为xml文件了,但在/data相关路径下没有找到。之后转念一想,会不会存在数据库里了,最后在/databases路径下找到了webviewCOOKIEsChromium.db这个文件,在COOKIEs表中,看到了登陆信息。 认证成功后,调用这个方法即可:
1 public static void removeCOOKIE(Context context) { 2 COOKIESyncManager.createInstance(context); 3 COOKIEManager COOKIEManager = COOKIEManager.getInstance(); 4 COOKIEManager.removeAllCOOKIE(); 5 COOKIESyncManager.getInstance().sync(); 6 }
也许我采用了一种比较笨的方法,把COOKIE的表都清空了,各位看客有好方法的话,请赐教哈。
5. 基本的流程是这样,设置密码,登陆等可自己替换。
新浪微博oauth认证实现APP第三方登陆