您的位置:首页 > 其它

Oauth认证流程

2013-10-29 23:50 155 查看
Oauth认证流程,主要是三个步骤

1,获取Request Token

2,对Request Token授权

3,获取Access Token

用代码实现

3个包,google所提供的基本的类库

com.google.gdata.util.common.base
oauth.signpost

这里包里面,主要修改的地方是 oauth.signpost.commonshttp.CommonsHttpOAuthProvider类里面,sendRequest方法里面

腾讯微博 不支持通过Header发送认证,他要求所有的请求通过get或post发送,所以把Header里的数据都取出来,放在entity里面post发送,

protected HttpResponse sendRequest(HttpRequest request) throws Exception {
Map headers = request.getAllHeaders();
String oauthHeader = (String) headers.get("Authorization");
headers.remove("Authorization");
HttpParameters httpParams = OAuth.oauthHeaderToParamsMap(oauthHeader);
List formParams = new ArrayList();
Set keys = httpParams.keySet();
String key;
String value;
for (Iterator iterator = keys.iterator(); iterator.hasNext(); formParams
.add(new BasicNameValuePair(key, URLDecoder.decode(value,
"UTF-8")))) {
key = (String) iterator.next();
value = httpParams.getFirst(key);
/*
* if(key.equals("oauth_timestamp")){ long longValue =
* Integer.parseInt(value); longValue = longValue - 8 * 60 * 60;
* value = new Long(longValue).toString(); }
*/
}

UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams,
"UTF-8");
HttpPost postRequest = (HttpPost) request.unwrap();
postRequest.setEntity(entity);
org.apache.http.HttpResponse response = httpClient.execute(postRequest);
return new HttpResponseAdapter(response);
}


org.marsdroid.oauth02

Constants类里面定义的变量

public class Constants {

//腾讯所分配的APP_KEY
public static final String CONSUMER_KEY 	= "99e9494ff07e42489f4ace16b63e1f47";
//腾讯所分配的APP_SECRET
public static final String CONSUMER_SECRET 	= "154f6f9ab4c1cf527f8ad8ab1f8e1ec9";
//3个url构成了整个Oauth认证流程的核心
//用于获取未授权的request token
public static final String REQUEST_URL 		= "https://open.t.qq.com/cgi-bin/request_token";
//用于获取access token
public static final String ACCESS_URL 		= "https://open.t.qq.com/cgi-bin/access_token";
//用于对未授权的request token进行授权
public static final String AUTHORIZE_URL 	= "https://open.t.qq.com/cgi-bin/authorize";

public static final String ENCODING 		= "UTF-8";

public static final String	OAUTH_CALLBACK_SCHEME	= "x-oauthflow";
public static final String	OAUTH_CALLBACK_HOST		= "callback";
//回调地址
//前面的是协议,后面的是地址
//这里协议和地址都是我们自己定义的
public static final String	OAUTH_CALLBACK_URL		= OAUTH_CALLBACK_SCHEME + "://" + OAUTH_CALLBACK_HOST;

}


OAuthRequestTokenTask

package org.marsdroid.oauth02;

import oauth.signpost.OAuthConsumer;
import oauth.signpost.OAuthProvider;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;

public class OAuthRequestTokenTask extends AsyncTask<Void, Void, Void>{

private Context context;
private OAuthConsumer consumer;
private OAuthProvider provider;

public OAuthRequestTokenTask(Context context, OAuthConsumer consumer,
OAuthProvider provider) {
super();
this.context = context;
this.consumer = consumer;
this.provider = provider;
}

@Override
protected Void doInBackground(Void... params) {
try {
System.out.println("请求Request Token之前" + consumer.getToken());
//retrieveRequestToken的第二个参数是回调URL

//把未授权的 Request Token consumer
final String url = provider.retrieveRequestToken(consumer, Constants.OAUTH_CALLBACK_URL);
System.out.println("请求Request Token之后" + consumer.getToken());
System.out.println("url---->" + url);
Uri uri = Uri.parse(url);//代表第二步要访问的url地址
//隐式的启动Activity 主要看后面参数 启动浏览器
//tel://21983129863 电话
//sms://767868698769 短信
//https://....... 浏览器
Intent intent = new Intent(Intent.ACTION_VIEW, uri).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_FROM_BACKGROUND);
context.startActivity(intent);
} catch(Exception e) {
e.printStackTrace();
}
return null;
}

}


客户在浏览器填写用户名和密码,网址是腾讯的,所以提交的数据不会提交给我们所写的应用,而是提交给腾讯的服务器

当浏览器启动 那个uri,就会启动清单文件中的activity

<activity android:name=".PrepareRequestTokenActivity" android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data android:scheme="x-oauthflow" android:host="callback" />
</intent-filter>
</activity>


而这个activity的launchMode是singleTask:是有且只有一个对象

而其他activity是每当启动一次就会启动一个新的activity对象

再启动将不会再调用onCreate方法,而调用onNewIntent方法

在这个方法里面intent.getData()。是腾讯返回给我们的数据



这就是腾讯返回给我们的认证码

PrepareRequestTokenActivity里面代码

@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this);
final Uri uri = intent.getData();
System.out.println(uri.toString());
if (uri != null
&& uri.getScheme().equals(Constants.OAUTH_CALLBACK_SCHEME)) {
new RetrieveAccessTokenTask(this, consumer, provider, prefs)
.execute(uri);
finish();
}
}

RetrieveAccessTokenTask类里面代码

public class RetrieveAccessTokenTask extends AsyncTask<Uri, Void, Void> {

final String TAG = "OAuth";

private Context	context;
private OAuthProvider provider;
private OAuthConsumer consumer;
private SharedPreferences prefs;

public RetrieveAccessTokenTask(Context context, OAuthConsumer consumer,OAuthProvider provider, SharedPreferences prefs) {
this.context = context;
this.consumer = consumer;
this.provider = provider;
this.prefs=prefs;
}

@Override
protected Void doInBackground(Uri...params) {
final Uri uri = params[0];

//getQueryParameter获取uri的参数 键值对 OAuth.OAUTH_VERIFIER键所对应的值取出来
final String oauth_verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER);

try {
provider.retrieveAccessToken(consumer, oauth_verifier);

final Editor edit = prefs.edit();
/*			最终得到OAuth.OAUTH_TOKEN
OAuth.OAUTH.TOKEN_SECRET*/
edit.putString(OAuth.OAUTH_TOKEN, consumer.getToken());
edit.putString(OAuth.OAUTH_TOKEN_SECRET, consumer.getTokenSecret());
edit.commit();
//以后和服务器交互的时候只有从sharepofsse里面取出来就可以了
String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");

consumer.setTokenWithSecret(token, secret);
context.startActivity(new Intent(context,MainActivity.class));

Log.i(TAG, "OAuth - Access Token Retrieved");

} catch (Exception e) {
Log.e(TAG, "OAuth - Access Token Retrieval Error", e);
}

return null;
}
}

代码下载地址http://download.csdn.net/detail/lj102800/6473609
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: