最近没什么事情做,想利用写空闲的时间来做点事情,看了看论坛,,觉得还是得做一些项目,从项目来学习新的知识,这样成长的才能更快一些。
于是就开始准备做一个新浪微博的客户端,于是乎就牵扯到了授权认证,说实话,这个玩意真不好弄,以前我看过OAuth1.0的认证,感觉太麻烦了,都不远弄。但是OAuth2.0明显比1.0简单,对于这块大家可以自己去网上看看原理。
说实话,新浪微博客户端的关于OAuth2.0的文档写的真的不是很好,我比较多的时间在这上面,现在就分享一下如何进行授权:
1、新建一个Android的项目。
2、注册一个新浪微博的账号,登入进去,然后拖动到页面底部找到“开发平台”并点击。这个页面上可以下载SDK,以及对注册一个应用。下载就不说了,那么下面说说如何注册一个应用。
2.1注册应用
单击“移动应用”,然后点击“接入应用”。
填写好“应用名称”点击创建。系统就会给你返回一个APP key和App Secret。
2.2下面就是要注册包名和签名,这个再下载的SDK文档中有说明,自己打开看就可以。
3.就是要将下载的SDK解压后,将WeiboSDK这个项目导入到Eclipse中。这个是一个library库,可以直接引用
4.将下面三个类拷贝到你的src下:
AccessTokenKeeper:
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import com.sina.weibo.sdk.auth.Oauth2AccessToken;
/**
* 该类定义了微博授权时所需要的参数。
*
* @author zengy
* @since 2015-6-16
*/
public class AccessTokenKeeper {
private static final String PREFERENCES_NAME = "com_weibo_sdk_android";
private static final String KEY_UID = "uid";
private static final String KEY_ACCESS_TOKEN = "access_token";
private static final String KEY_EXPIRES_IN = "expires_in";
private static final String KEY_REFRESH_TOKEN = "refresh_token";
/**
* 保存 Token 对象到 SharedPreferences。
*
* @param context 应用程序上下文环境
* @param token Token 对象
*/
public static void writeAccessToken(Context context, Oauth2AccessToken token) {
if (null == context || null == token) {
return;
}
SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_APPEND);
Editor editor = pref.edit();
editor.putString(KEY_UID, token.getUid());
editor.putString(KEY_ACCESS_TOKEN, token.getToken());
editor.putString(KEY_REFRESH_TOKEN, token.getRefreshToken());
editor.putLong(KEY_EXPIRES_IN, token.getExpiresTime());
editor.commit();
}
/**
* 从 SharedPreferences 读取 Token 信息。
*
* @param context 应用程序上下文环境
*
* @return 返回 Token 对象
*/
public static Oauth2AccessToken readAccessToken(Context context) {
if (null == context) {
return null;
}
Oauth2AccessToken token = new Oauth2AccessToken();
SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_APPEND);
token.setUid(pref.getString(KEY_UID, ""));
token.setToken(pref.getString(KEY_ACCESS_TOKEN, ""));
token.setRefreshToken(pref.getString(KEY_REFRESH_TOKEN, ""));
token.setExpiresTime(pref.getLong(KEY_EXPIRES_IN, 0));
return token;
}
/**
* 清空 SharedPreferences 中 Token信息。
*
* @param context 应用程序上下文环境
*/
public static void clear(Context context) {
if (null == context) {
return;
}
SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_APPEND);
Editor editor = pref.edit();
editor.clear();
editor.commit();
}
}
/**
* 该类定义了微博授权时所需要的参数。
*
* @author zengy
* @since 2016-6-16
*/
public interface Constants {
/** 当前 DEMO 应用的 APP_KEY,第三方应用应该使用自己的 APP_KEY 替换该 APP_KEY */
public static final String APP_KEY = "1663004349";
/**
* 当前 DEMO 应用的回调页,第三方应用可以使用自己的回调页。
*
* <p>
* 注:关于授权回调页对移动客户端应用来说对用户是不可见的,所以定义为何种形式都将不影响,
* 但是没有定义将无法使用 SDK 认证登录。
* 建议使用默认回调页:https://api.weibo.com/oauth2/default.html
* </p>
*/
public static final String REDIRECT_URL = "https://api.weibo.com/oauth2/default.html";
/**
* Scope 是 OAuth2.0 授权机制中 authorize 接口的一个参数。通过 Scope,平台将开放更多的微博
* 核心功能给开发者,同时也加强用户隐私保护,提升了用户体验,用户在新 OAuth2.0 授权页中有权利
* 选择赋予应用的功能。
*
* 我们通过新浪微博开放平台-->管理中心-->我的应用-->接口管理处,能看到我们目前已有哪些接口的
* 使用权限,高级权限需要进行申请。
*
* 目前 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";
}
import java.text.SimpleDateFormat;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;
import com.sina.weibo.sdk.auth.AuthInfo;
import com.sina.weibo.sdk.auth.Oauth2AccessToken;
import com.sina.weibo.sdk.auth.WeiboAuthListener;
import com.sina.weibo.sdk.auth.sso.SsoHandler;
import com.sina.weibo.sdk.exception.WeiboException;
/**
* 该类主要演示如何进行授权、SSO登陆。
*
* @author SINA
* @since
*/
public class WBAuthActivity extends Activity {
private static final String TAG = "weibosdk";
/** 显示认证后的信息,如 AccessToken */
private TextView mTokenText;
private AuthInfo mAuthInfo;
/** 封装了 "access_token","expires_in","refresh_token",并提供了他们的管理功能 */
private Oauth2AccessToken mAccessToken;
/** 注意:SsoHandler 仅当 SDK 支持 SSO 时有效 */
private SsoHandler mSsoHandler;
/**
* @see {@link Activity#onCreate}
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_auth);
// 获取 Token View,并让提示 View 的内容可滚动(小屏幕可能显示不全)
mTokenText = (TextView) findViewById(R.id.token_text_view);
// 创建微博实例
//mWeiboAuth = new WeiboAuth(this, Constants.APP_KEY, Constants.REDIRECT_URL, Constants.SCOPE);
// 快速授权时,请不要传入 SCOPE,否则可能会授权不成功
mAuthInfo = new AuthInfo(this, Constants.APP_KEY, Constants.REDIRECT_URL, Constants.SCOPE);
mSsoHandler = new SsoHandler(WBAuthActivity.this, mAuthInfo);
// SSO 授权, ALL IN ONE 如果手机安装了微博客户端则使用客户端授权,没有则进行网页授权
findViewById(R.id.obtain_token_via_signature).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mSsoHandler.authorize(new AuthListener());
}
});
// 从 SharedPreferences 中读取上次已保存好 AccessToken 等信息,
// 第一次启动本应用,AccessToken 不可用
mAccessToken = AccessTokenKeeper.readAccessToken(this);
if (mAccessToken.isSessionValid()) {
updateTokenView(true);
}
}
/**
* 当 SSO 授权 Activity 退出时,该函数被调用。
*
* @see {@link Activity#onActivityResult}
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// SSO 授权回调
// 重要:发起 SSO 登陆的 Activity 必须重写 onActivityResults
if (mSsoHandler != null) {
mSsoHandler.authorizeCallBack(requestCode, resultCode, data);
}
}
/**
* 微博认证授权回调类。
* 1. SSO 授权时,需要在 {@link #onActivityResult} 中调用 {@link SsoHandler#authorizeCallBack} 后,
* 该回调才会被执行。
* 2. 非 SSO 授权时,当授权结束后,该回调就会被执行。
* 当授权成功后,请保存该 access_token、expires_in、uid 等信息到 SharedPreferences 中。
*/
class AuthListener implements WeiboAuthListener {
@Override
public void onComplete(Bundle values) {
// 从 Bundle 中解析 Token
mAccessToken = Oauth2AccessToken.parseAccessToken(values);
if (mAccessToken.isSessionValid()) {
// 显示 Token
updateTokenView(false);
// 保存 Token 到 SharedPreferences
AccessTokenKeeper.writeAccessToken(WBAuthActivity.this, mAccessToken);
Toast.makeText(WBAuthActivity.this,
R.string.weibosdk_demo_toast_auth_success, Toast.LENGTH_SHORT).show();
} else {
// 以下几种情况,您会收到 Code:
// 1. 当您未在平台上注册的应用程序的包名与签名时;
// 2. 当您注册的应用程序包名与签名不正确时;
// 3. 当您在平台上注册的包名和签名与您当前测试的应用的包名和签名不匹配时。
String code = values.getString("code");
String message = getString(R.string.weibosdk_demo_toast_auth_failed);
if (!TextUtils.isEmpty(code)) {
message = message + "\nObtained the code: " + code;
}
Toast.makeText(WBAuthActivity.this, message, Toast.LENGTH_LONG).show();
}
}
@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();
}
}
/**
* 显示当前 Token 信息。
*
* @param hasExisted 配置文件中是否已存在 token 信息并且合法
*/
private void updateTokenView(boolean hasExisted) {
String date = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(
new java.util.Date(mAccessToken.getExpiresTime()));
String format = getString(R.string.weibosdk_demo_token_to_string_format_1);
mTokenText.setText(String.format(format, mAccessToken.getToken(), date));
String message = String.format(format, mAccessToken.getToken(), date);
if (hasExisted) {
message = getString(R.string.weibosdk_demo_token_has_existed) + "\n" + message;
}
mTokenText.setText(message);
}
}
activity_auth.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".WBAuthActivity" >
<Button
android:id="@+id/obtain_token_via_signature"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="left|center_vertical"
android:text="@string/weibosdk_demo_obtain_token_via_sso_all_in_one" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textSize="16sp"
android:textStyle="bold"
android:text="@string/weibosdk_demo_token_info" />
<TextView
android:id="@+id/token_text_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="12sp" />
</LinearLayout>
这时候工程肯定得报错的,别急,是因为还有很多工作没有完成。
1.需要把刚刚导入的weiboSDK作为Library加入到我们新建的工程中:
这样工程就不会报错了,但是这样还是不行,就在这个地方,我懵逼了,看了好一会,妈蛋,新浪微博官方给的文档既然没有写,被坑的不行不行的了。
在清单文件中需要加入权限以外,还需要配置
<activity
android:name="com.sina.weibo.sdk.component.WeiboSdkBrowser"
android:configChanges="keyboardHidden|orientation"
android:exported="false"
android:windowSoftInputMode="adjustResize" >
这个必须要有,不然会出现找不到该类!
好了,大致就是这样一个流程,大家看的时候要结合在新浪官网下的文档一起看,这样就能快集成。
顺带说一句,我这个版本是v3.1.1的!不同版本可能文档不一样哈
枫