关于微博授权的流程

微博授权V2.5,目前最新V3.0

Android SDK地址:https://github.com/sinaweibosdk/weibo_android_sdk

在应用中使用SSO授权时,首先需要做的是实例化授权类对象:

mWeiboAuth = new WeiboAuth(this, Constants.APP_KEY,
				Constants.REDIRECT_URL, Constants.SCOPE);
分别指定

APP_KEY:应用密钥

REDIRECT_URL:回调地址,创建应用时指定

SCOPE:权限接口

然后创建SSOHandler,并传入监听:

mSsoHandler = new SsoHandler(SSOAuthActivity.this, mWeiboAuth);
mSsoHandler.authorize(new AuthListener());
监听必须是实现WeiboAuthListener接口的类,这个里面主要是处理授权过程中的状态:

public abstract interface WeiboAuthListener
{
  public abstract void onComplete(Bundle paramBundle);

  public abstract void onWeiboException(WeiboException paramWeiboException);

  public abstract void onCancel();
}
提交:保存登陆信息的bundle

异常:获取异常信息,主要是web授权时

取消:截获触发取消授权的信息

在内部的授权流程中,采用SSO授权时,首先会检测微博客户端是否安装,主要方法是采用启动微博客户端的特定service:com.sina.weibo.remotessoservice。通过绑定本地的service并与其通信。

启动方式:

 private boolean bindRemoteSSOService(Context context, String packageName)
  {
    String tempPkgName = (TextUtils.isEmpty(packageName)) || (packageName.trim().equals("")) ? 
      "com.sina.weibo" : packageName;
    Intent intent = new Intent("com.sina.weibo.remotessoservice");
    intent.setPackage(tempPkgName);

    if (!context.bindService(intent, this.mConnection, 1)) {
      intent = new Intent("com.sina.weibo.remotessoservice");
      return context.bindService(intent, this.mConnection, 1);
    }

    return true;
  }

ServiceConnection对象:

private ServiceConnection mConnection = new ServiceConnection()
  {
    public void onServiceDisconnected(ComponentName name) {
      SsoHandler.this.mWeibo.anthorize(SsoHandler.this.mAuthListener);
    }

    public void onServiceConnected(ComponentName name, IBinder service)
    {
      RemoteSSO remoteSSOservice = RemoteSSO.Stub.asInterface(service);
      try {
        String ssoPackageName = remoteSSOservice.getPackageName();
        String ssoActivityName = remoteSSOservice.getActivityName();
        boolean singleSignOnStarted = SsoHandler.this.startSingleSignOn(ssoPackageName, ssoActivityName);

        if (!singleSignOnStarted)
          SsoHandler.this.mWeibo.anthorize(SsoHandler.this.mAuthListener);
      }
      catch (RemoteException e) {
        e.printStackTrace();
      }
    }
  };

在与service链接成功时就会继续使用SSO,当失败时会自动转成web授权。

在web授权中,主要是通过打开一个自定义的Dialog:

  public void anthorize(WeiboAuthListener listener)
  {
    authorize(listener, 1);
  }

  public void authorize(WeiboAuthListener listener, int type)
  {
    startDialog(listener, type);
  }

  private void startDialog(WeiboAuthListener listener, int type)
  {
    if (listener == null) {
      return;
    }

    LinkedHashMap requestParams = new LinkedHashMap();

    requestParams.put("client_id", this.mAuthInfo.mAppKey);
    requestParams.put("redirect_uri", this.mAuthInfo.mRedirectUrl);
    requestParams.put("scope", this.mAuthInfo.mScope);
    requestParams.put("response_type", "code");
    requestParams.put("display", "mobile");

    if (1 == type) {
      requestParams.put("packagename", this.mAuthInfo.mPackageName);
      requestParams.put("key_hash", this.mAuthInfo.mKeyHash);
    }

    String url = "https://open.weibo.cn/oauth2/authorize?" + Utility.packUrl(requestParams);
    if (!NetworkHelper.hasInternetPermission(this.mContext)) {
      UIUtils.showAlert(this.mContext, "Error", "Application requires permission to access the Internet");
    }
    else if (NetworkHelper.isNetworkAvailable(this.mContext)) {
      new WeiboDialog(this.mContext, url, listener, this).show();
    } else {
      String networkNotAvailable = ResourceManager.getString(this.mContext, 2);
      LogUtil.i("Weibo_web_login", "String: " + networkNotAvailable);
      UIUtils.showToast(this.mContext, networkNotAvailable, 0);
    }
  }
在弹出对话框之前,进行网络判断,
应用是否授予网络权限

网络可用,弹出对话框

网络不可用的提示

接下来就要看WeiboDialog类,它继承自Dialog。先看构造方法:

  public WeiboDialog(Context context, String authUrl, WeiboAuthListener listener, WeiboAuth weibo)
  {
    super(context, theme);
    this.mAuthUrl = authUrl;//授权地址
    this.mListener = listener;//监听
    this.mContext = context;//上下文
    this.mWeibo = weibo;//WeiboAuth对象
  }
主要是一些实例化操作。

  protected void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);

    initWindow();

    initLoadingDlg();

    initWebView();

    initCloseButton();
  }
在oncreate中,是进行界面的初始化,主要的地方是在webview。

webview中有这样一句:

this.mWebView.setWebViewClient(new WeiboWebViewClient(null));
来进行事件处理。

private class WeiboWebViewClient extends WebViewClient
  {
    private boolean isCallBacked = false;

    private WeiboWebViewClient() {
    }
    public boolean shouldOverrideUrlLoading(WebView view, String url) { LogUtil.i("WeiboDialog", "load URL: " + url);

      if (url.startsWith("sms:")) {
        Intent sendIntent = new Intent("android.intent.action.VIEW");
        sendIntent.putExtra("address", url.replace("sms:", ""));
        sendIntent.setType("vnd.android-dir/mms-sms");
        WeiboDialog.this.getContext().startActivity(sendIntent);
        return true;
      }
      return super.shouldOverrideUrlLoading(view, url);
    }

    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
    {
      LogUtil.d("WeiboDialog", "onReceivedError: errorCode = " + errorCode + 
        ", description = " + description + 
        ", failingUrl = " + failingUrl);
      super.onReceivedError(view, errorCode, description, failingUrl);

      if (WeiboDialog.this.mListener != null) {
        WeiboDialog.this.mListener.onWeiboException(new WeiboDialogException(description, errorCode, failingUrl));
      }
      WeiboDialog.this.dismiss();
    }

    public void onPageStarted(WebView view, String url, Bitmap favicon)
    {
      LogUtil.d("WeiboDialog", "onPageStarted URL: " + url);
      if ((url.startsWith(WeiboDialog.this.mWeibo.getAuthInfo().getRedirectUrl())) && 
        (!this.isCallBacked)) {
        this.isCallBacked = true;
        WeiboDialog.this.handleRedirectUrl(url);
        view.stopLoading();
        WeiboDialog.this.dismiss();

        return;
      }

      super.onPageStarted(view, url, favicon);

      if ((!WeiboDialog.this.mIsDetached) && (WeiboDialog.this.mLoadingDlg != null) && (!WeiboDialog.this.mLoadingDlg.isShowing()))
        WeiboDialog.this.mLoadingDlg.show();
    }

    public void onPageFinished(WebView view, String url)
    {
      LogUtil.d("WeiboDialog", "onPageFinished URL: " + url);
      super.onPageFinished(view, url);
      if ((!WeiboDialog.this.mIsDetached) && (WeiboDialog.this.mLoadingDlg != null)) {
        WeiboDialog.this.mLoadingDlg.dismiss();
      }
      WeiboDialog.this.mWebView.setVisibility(0);
    }
  }
在页面开始加载时的方法中有一个判断:

 if ((url.startsWith(WeiboDialog.this.mWeibo.getAuthInfo().getRedirectUrl())) && 
        (!this.isCallBacked)) {
        this.isCallBacked = true;
        WeiboDialog.this.handleRedirectUrl(url);
        view.stopLoading();
        WeiboDialog.this.dismiss();

        return;
      }
因为最早的时候在创建应用时给定了一个回调页的地址,当要加载的页面地址开头是回调页时,就开始进行解析用户信息和授权信息,因为在这个返回的的url中包含四个参数:

access_token,remind_in,expires_in,uid。

access_token代表口令信息,remind_in和expires_in都代表过期时间,uid代表被授权用户id。

 private void handleRedirectUrl(String url)
  {
    Bundle values = Utility.parseUrl(url);

    String errorType = values.getString("error");
    String errorCode = values.getString("error_code");
    String errorDescription = values.getString("error_description");

    if ((errorType == null) && (errorCode == null))
      this.mListener.onComplete(values);
    else
      this.mListener.onWeiboException(
        new WeiboAuthException(errorCode, errorType, errorDescription));
  }
Utility中提供了解析url的方法。

至于其中的另外一个条件:

(!this.isCallBacked)
我的理解是:因为返回的url的状态码是301,意思是客户请求的文档在其他地方,新的URL在Location头中给出,浏览器应该自动地访问新的URL,也就是回调页,这个时候要做的判断就是,这个页面的url开头也是回调页,所以就要用isCallbacked进行阻止,意思是已经回调过了,就不会再去解析它了,其实里面也是空的,还有一点就是,解析过一次,这个webview就会被关掉,这个变量可能是防止解析出错延时做的措施。

接下来,解析到的信息就被放进了bundle,在判断其中信息无误后调用onComplete(value)。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值