新浪微博oauth认证实现APP第三方登陆

最近在做一个图片分享的APP,为增加用户入口,便于注册,先采用新浪微博作为第三方的入口。 我采用的注册流程如下:

 技术分享

  • 微博的开发者管理平台登录注册过程在这里就不提了,各位看官请自行百度。
  • 介绍WebView的方式进行认证注册

  1. 考虑到日后可能添加其他第三方入口,在登陆页面添加如下内容:
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. 基本的流程是这样,设置密码,登陆等可自己替换。

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。