Oauth认证流程

来源:互联网 发布:每日日程安排软件 编辑:程序博客网 时间:2024/04/30 22:39

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发送认证,他要求所有的请求通过getpost发送,所以把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_KEYpublic static final String CONSUMER_KEY = "99e9494ff07e42489f4ace16b63e1f47";//腾讯所分配的APP_SECRETpublic static final String CONSUMER_SECRET = "154f6f9ab4c1cf527f8ad8ab1f8e1ec9";//3个url构成了整个Oauth认证流程的核心//用于获取未授权的request tokenpublic static final String REQUEST_URL = "https://open.t.qq.com/cgi-bin/request_token";//用于获取access tokenpublic 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 StringOAUTH_CALLBACK_SCHEME= "x-oauthflow";public static final StringOAUTH_CALLBACK_HOST= "callback";//回调地址  //前面的是协议,后面的是地址//这里协议和地址都是我们自己定义的public static final StringOAUTH_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;}@Overrideprotected Void doInBackground(Void... params) {try {System.out.println("请求Request Token之前" + consumer.getToken());//retrieveRequestToken的第二个参数是回调URL
//把未授权的 Request Token consumerfinal 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>

而这个activitylaunchModesingleTask:是有且只有一个对象

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

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

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

 

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

PrepareRequestTokenActivity里面代码

@Overridepublic 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 Contextcontext;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;}@Overrideprotected 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_TOKENOAuth.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

原创粉丝点击