使用Oauth2.0實現微博授權登錄

本文章參考資料:
http://blog.csdn.net/highboys/article/details/52139268
http://blog.csdn.net/yypsober/article/details/51720355?locationNum=3&fps=1

現在實現第三方授權登錄都是通過Oauth2.0來實現,然而關於Oauth2.0的理解和用法,我現在還在學習中,具體可以看這裏。雖然實現方式有各種各樣,我這裏就實現一下最常規的通過Oauth2.0實現微博授權登錄,具體的實現如下圖

這裏寫圖片描述
這裏寫圖片描述這裏寫圖片描述
如上面的圖,總共用了三種實現方式
1.SSO單點登錄:前提是你的手機上裝了微博的app,否則報錯
2.web頁面登錄:彈出一個web界面,然後實現賬號密碼登錄
3.All in one方式授權登錄:自動識別如果手機擁有微博app就通過SSO單點登錄,沒有的話就通過web頁面登錄,該功能比較人性化,這也是第三方登錄常用的方式

接下來就開始正式的教程了

一、到http://open.weibo.com/註冊一個微博開發者賬號

首先,註冊->註冊成功->微連接->移動應用->立即接入->填寫名字,應用創建->打開應用信息->基礎信息按要求填寫:如下
這裏寫圖片描述
這裏的報名就是你創建android工程時的包名,Android簽名的話頁面有提示使用他提示的android簽名生成工具生成,你只需要將你創建的app運行在你手機上,然後再裝上android簽名生成,複製上去(所以第一步其實應該是先創建一個project的)其他一些基本按要求就行
另外還需要 應用信息->高級信息 填寫回調頁這裏寫圖片描述
我這裏填寫的是http://www.sina.com,一般都是填寫微博的默認回調頁http://api.weibo.com/oauth2/default.html,道理來說也可以用自己公司網站什麼的

二、前期準備

  • 下載微博的SDK:http://open.weibo.com/wiki/SDK
  • 在你創建的project中的main文件夾下創建jniLibs文件夾,將微博SDK的內容拷貝到這個文件夾下
    這裏寫圖片描述
  • 另外還需導入weiboSDKCore_3.1.4.jar和weibosdk.jar
    這裏寫圖片描述

三、邏輯整理

  • 我這裏想實現兩個Activity,第一個Activity通過這三個按鈕實現登錄,第二個activity顯示用戶的信息,所以有下圖
    這裏寫圖片描述
  • 看到是否有一個Constants,這裏存放着一些公用的信息,例如:token,用戶的信息,微博微應用創建時生成的App Key等等,代碼如下
Constants.java
public class Constants {
    //用戶信息
    public static String name = null;//名字
    public static String gender = null;//性別
    public static String location = null;//歸屬地
    public static String token = null;
    /** 當前 DEMO 應用的 APP_KEY,第三方應用應該使用自己的 APP_KEY 替換該 APP_KEY */
    public static final String APP_KEY      = "490704571";

    //填寫自己創建時自己填的回調頁url
    public static final String REDIRECT_URL = "http://www.sina.com";
     /*
     * Scope 是 OAuth2.0 授權機制中 authorize 接口的一個參數。
     * 目前 Scope 支持傳入多個 Scope 權限,用逗號分隔。
     * 有關哪些 OpenAPI 需要權限申請,請查看:http://open.weibo.com/wiki/%E5%BE%AE%E5%8D%9AAPI
     * 關於 Scope 概念及注意事項,請查看:http://open.weibo.com/wiki/Scope
     */
    public static final String SCOPE =
            "email,direct_messages_read,direct_messages_write,"
                    + "friendships_groups_read,friendships_groups_write,statuses_to_me_read,"
                    + "follow_app_official_microblog," + "invitation_write";
}

第二個Activity如下
這裏寫圖片描述
是的,就這麼簡陋(其實是拿了別人的代碼懶得改)基本邏輯應該清楚了,那接下來應該是第三部了

四、編碼

主要實現是在OauthActivity上。

  • 首先先把基本代碼碼好,初始化按鈕和使用weiboSDK的WeiboAuthListener接口
public class OAuthActivity extends AppCompatActivity implements View.OnClickListener,WeiboAuthListener{

    //登錄按鈕
    private Button btnSsoLogIn;
    private Button btnWebLogIn;
    private Button btnAllInOneLogIn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        initView();
    }
    private void initView() {
        btnSsoLogIn = (Button) findViewById(R.id.logIn_btn_SsoLogin);
        btnSsoLogIn.setOnClickListener(this);
        btnWebLogIn = (Button) findViewById(R.id.logIn_btn_WebLogin);
        btnWebLogIn.setOnClickListener(this);
        btnAllInOneLogIn = (Button) findViewById(R.id.logIn_btn_AllInOneLogin);
        btnAllInOneLogIn.setOnClickListener(this);
    }
     /**
     * 微博認證授權回調類。
     * 1. SSO 授權時,需要在 {@link #onActivityResult} 中調用 {@link SsoHandler#authorizeCallBack} 後,
     * 該回調纔會被執行。
     * 2. 非 SSO 授權時,當授權結束後,該回調就會被執行。
     * 當授權成功後,請保存該 access_token、expires_in、uid 等信息到 SharedPreferences 中。
     */
    @Override
    public void onComplete(Bundle bundle) {
    }
    @Override
    public void onWeiboException(WeiboException e) {
        Toast.makeText(OAuthActivity.this, "授權異常", Toast.LENGTH_SHORT).show();
    }
    @Override
    public void onCancel() {
        Toast.makeText(OAuthActivity.this, "授權取消", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onClick(View v) {
}
  • 接下來是實現功能的具體細節了。先定義以下幾個變量
    /**
     * 注意:SsoHandler 僅當 SDK 支持 SSO 時有效
     */
    private SsoHandler mSsoHandler;
    private AuthInfo mAuthInfo;
    /**
     * 封裝了 "access_token","expires_in","refresh_token",並提供了他們的管理功能
     */
    private Oauth2AccessToken mAccessToken;
    //獲取用戶信息的接口(需要先把官方提供的weibosdk庫引入到工程當中來)
    UsersAPI mUsersAPI;

然後在onCreate中實現

        // 快速授權時,請不要傳入 SCOPE,否則可能會授權不成功
        mAuthInfo = new AuthInfo(this, Constants.APP_KEY, Constants.REDIRECT_URL, Constants.SCOPE);
        mSsoHandler = new SsoHandler(this, mAuthInfo);

爲幾個按鈕實現監聽

@Override
    public void onClick(View v) {
        switch (v.getId()) {
            //sso授權,僅客戶端
            case R.id.logIn_btn_SsoLogin:
                startSsoWeiBoLogIn();
                break;
            //web授權
            case R.id.logIn_btn_WebLogin:
                startWebWeiBoLogIn();
                break;
            //自動檢測,若有客戶端,則用sso授權,若沒有客戶端則用web授權
            case R.id.logIn_btn_AllInOneLogin:
                startAllInOneWeiBoLogIn();
                break;
        }
    }

各按鈕的動作

    /**
     * all in one 方式授權,自動檢測
     */
    private void startAllInOneWeiBoLogIn() {
        mSsoHandler.authorize(this);
    }
    /**
     * Web授權
     */
    private void startWebWeiBoLogIn() {
        mSsoHandler.authorizeWeb(this);
    }
    /**
     * SSO授權,僅客戶端
     */
    private void startSsoWeiBoLogIn() {
        mSsoHandler.authorizeClientSso(this);
        //通過accessToken獲取用戶信息
    }
  • 修改重寫的onComplete和重洗函數onActivityResult
 @Override
    public void onComplete(Bundle bundle) {
        //從Bundle中解析Token
        mAccessToken = Oauth2AccessToken.parseAccessToken(bundle);
        if (mAccessToken.isSessionValid()) {//授權成功
            Constants.token = mAccessToken.getToken();
            Toast.makeText(OAuthActivity.this, "登陸成功", Toast.LENGTH_SHORT).show();
            //獲取用戶具體信息
            getUserInfo();
            //跳轉頁面
            Intent intent = new Intent(OAuthActivity.this,MainActivity.class);
            startActivity(intent);
            finish();
        } else {
            /**
             *  以下幾種情況,您會收到 Code:
             * 1. 當您未在平臺上註冊應用程序的包名與簽名時;
             * 2. 當您註冊的應用程序包名與簽名不正確時;
             * 3. 當您在平臺上註冊的包名和簽名與您當前測試的應用的包名和簽名不匹配時。
             */
            String code = bundle.getString("code");//直接從bundle裏邊獲取
            if (!TextUtils.isEmpty(code)) {
                Toast.makeText(OAuthActivity.this, "簽名不正確", Toast.LENGTH_SHORT).show();
            }
        }
//            String phoneNum = mAccessToken.getPhoneNum();//通過手機短信授權登錄時可以拿到,此demo未實現此種授權方式
    }

    /**
     * 1.僅sso授權時,當 SSO 授權 Activity 退出時,該函數被調用。
     * 2.僅
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //SSO 授權回調
        //重要:發起sso登錄的activity必須重寫onActivtyResults
        if (mSsoHandler != null) {
            mSsoHandler.authorizeCallBack(requestCode, resultCode, data);
        }
    }
  • 還有就是獲取用戶信息
 /**
     * 獲取用戶個人信息
     */
    private void getUserInfo() {
        //獲取用戶信息接口
        mUsersAPI = new UsersAPI(OAuthActivity.this,Constants.APP_KEY,mAccessToken);
        System.out.println("mUsersAPI  ----->   " + mUsersAPI.toString());

        //調用接口
        long uid = Long.parseLong(mAccessToken.getUid());
        System.out.println("--------------uid-------------->    " + uid);
        mUsersAPI.show(uid, mListener);//將uid傳遞到listener中,通過uid在listener回調中接收到該用戶的json格式的個人信息
    }

    /**
     * 實現異步請求接口回調,並在回調中直接解析User信息
     */
    private RequestListener mListener = new RequestListener() {
        @Override
        public void onComplete(String response) {
            if (!TextUtils.isEmpty(response)) {
                //調用User#parse將JSON串解析成User對象
                User user = User.parse(response);
                String nickName = user.screen_name;
                Constants.name = user.screen_name;
                Constants.gender = user.gender;
                Constants.location = user.location;
//                Toast.makeText(LogInActivity.this, "用戶的暱稱: " + nickName, Toast.LENGTH_SHORT).show();
            }
        }

        /**
         *如果運行測試的時候,登錄的賬號不是註冊應用的賬號,那麼需要去:
         *開放平臺-》管理中心-》應用信息-》測試信息-》添加測試賬號(填寫用戶暱稱)!
         * 否則便會拋出以下異常
         */
        @Override
        public void onWeiboException(WeiboException e) {
            e.printStackTrace();
            Toast.makeText(OAuthActivity.this, "獲取用戶個人信息 出現異常", Toast.LENGTH_SHORT).show();
        }
    };

最後

  • 道理來說是大功告成了
  • 上傳我測試用的源代碼,單擊這裏下載
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章