最近公司要做一个sdk,仿照微博开放平台。要写移动sdk,并且采用H5页面进行授权。看了几天微博SDK源码,终于理解了微博如何做到通过H5页面授权,并回调移动端的方法返回授权码,access Token等信息,在此做个记录。
对于用户认证采用OAuth2.0协议,以下是从微博copy过来的Oauth2授权机制。
OAuth2.0协议这里不作具体分析。主要通过微博sdk的demo代码(版本:3.1.4)分析如何通过h5方式授权。
demo的授权页面
这个页面对应 WBAuthActivity
微博授权按钮操作:
// SSO 授权, 仅Web
findViewById(R.id.obtain_token_via_web).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mSsoHandler.authorizeWeb(new AuthListener());
}
});
这里调用了SsoHandler的authorizeWeb方法,并创建了一个回调监听。最终就是在这个回调监听中获取授权通过后的token信息。
class AuthListener implements WeiboAuthListener {
@Override
public void onComplete(Bundle values) {
// 从 Bundle 中解析 Token
mAccessToken = Oauth2AccessToken.parseAccessToken(values);
// 省略其他代码
}
@Override
public void onCancel() {
Toast.makeText(WBAuthActivity.this,
R.string.weibosdk_demo_toast_auth_canceled, Toast.LENGTH_LONG).show();
}
@Override
public void onWeiboException(WeiboException e) {
Toast.makeText(WBAuthActivity.this,
"Auth exception : " + e.getMessage(), Toast.LENGTH_LONG).show();
}
}
这个回调是何时进行,怎么进行回调的呢?
先看SsoHandler的authorizeWeb方法
(这里是Android Studio 反编译的微博weibosdkcore_release.jar,有些显示不正确,但不影响阅读)
public void authorizeWeb(WeiboAuthListener listener) {
this.authorize('胍', listener, SsoHandler.AuthType.WebOnly);
WbAppActivator.getInstance(this.mAuthActivity, this.mAuthInfo.getAppKey()).activateApp();
}
首先会调用该类的authorize方法,并将类型设置为WebOnly。 authorise方法如下
private void authorize(int requestCode, WeiboAuthListener listener, SsoHandler.AuthType authType) { this.mSSOAuthRequestCode = requestCode; this.mAuthListener = listener; boolean onlyClientSso = false; if(authType == SsoHandler.AuthType.SsoOnly) { onlyClientSso = true; } // 会走到这个分支 if(authType == SsoHandler.AuthType.WebOnly) { if(listener != null) { this.mWebAuthHandler.anthorize(listener); } } else {
// 这里进行的sso方式授权,不做分析 boolean bindSucced = this.bindRemoteSSOService(this.mAuthActivity.getApplicationContext()); if(!bindSucced) { if(onlyClientSso) { if(this.mAuthListener != null) { this.mAuthListener.onWeiboException(new WeiboException("not install weibo client!!!!!")); } } else { this.mWebAuthHandler.anthorize(this.mAuthListener); } } } }
可以看到会调用WebAuthHandler的anthorize方法
public void anthorize(WeiboAuthListener listener) {
this.authorize(listener, 1);
}
public void authorize(WeiboAuthListener listener, int type) {
this.startDialog(listener, type);
}
private void startDialog(WeiboAuthListener listener, int type) {
if(listener != null) {
WeiboParameters requestParams = new WeiboParameters(