Android performing OAuth2 Authorization using WebView

原文 http://www.learn2crack.com/2014/01/android-oauth2-webview.html?utm_source=tuicool


OAuth is an open standard for authorization. OAuth2 authorization uses access token to access APIs instead of using username and password. In OAuth2 method we would initially request Authorization code from the Authority using scope, redirect URL, and client id,then exchange the code with client id and client secret to get access token and refresh token. In Android WebView method can be applicable for all types of Services. In this tutorial we are going to see how to perform OAuth2 authorization in Android using WebView to obtain the Access Token for performing API calls. To perform OAuth2 Authorization using Android  AccountManager refer the tutorial Android Google OAuth2 using AccountManager and making API calls

Enable Google API for making Request

1. Go to Google API Console.
2. Create a new project. In the Dialog give a Project name and Project- ID, then press next.

Android performing OAuth2 Authorization using WebView

3.In the APIs & auth pane Turn on a Service. Here I am enabling URL Shortener API.
4. In the credentials pane select CREATE NEW CLIENT ID.
5. Select Application type as Installed application and select Installed application type as Other.
6. Finally select Create client ID.
8. Now your application is eligible for making API calls. Note down the Client Id and Client Secret.

Android performing OAuth2 Authorization using WebView

Creating Project

Create a new project in eclipse as File->New->Android Application Project. In the Dialog give Application name and Package name. Create the Main Activity as MainActivity.java and Main layout asactivity_main.xml. Here my applicaion name is WebOAuth2 and my package name islearn2crack.weboauth2.

Android performing OAuth2 Authorization using WebView

Download Complete Project

WebOAuth2
WebOAuth2 
WebOAuth2.zip
Version: 1.0
1.4 MiB
324 Downloads
DETAILS

Creating Layout

The layout has a single button widget to start the WebView dialog.

activity_main.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"
     tools:context = ".MainActivity" >
     < TextView
         android:layout_width = "wrap_content"
         android:layout_height = "wrap_content"
         android:layout_gravity = "center"
         android:textSize = "25sp"
         android:text = "Google OAuth2 WebView" />
      < Button
         android:layout_width = "wrap_content"
         android:layout_height = "wrap_content"
         android:layout_gravity = "center"
         android:id = "@+id/auth"
         android:text = "Sign in with Google" />
      < TextView
         android:layout_width = "wrap_content"
         android:layout_height = "wrap_content"
         android:id = "@+id/Access"
         android:autoLink = "all"
         android:textIsSelectable = "true"
         android:layout_gravity = "center"
         android:textSize = "10sp" />
</ LinearLayout >

The next layout is for WebView dialog. It contains a WebView widget which loads the Authorization webpage.

auth_dialog.xml
<? xml version = "1.0" encoding = "utf-8" ?>
< LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
     android:layout_width = "match_parent"
     android:layout_height = "match_parent"
     android:orientation = "vertical" >
       < WebView
         android:layout_width = "wrap_content"
         android:layout_height = "wrap_content"
         android:id = "@+id/webv" />
</ LinearLayout >

Creating Activity

Before proceeding to the MainActivity class we must create a GetAccessToken class which makes http request with the authorization code to get the Access Token, Time, Refresh Token in JSON format. The http request has five parameters which should be in url form encoded format.

GetAccessToken.java
package learn2crack.weboauth2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class GetAccessToken {
     static InputStream is = null ;
     static JSONObject jObj = null ;
     static String json = "" ;
     public GetAccessToken() {
     }
     List<NameValuePair> params = new ArrayList<NameValuePair>();
     Map<String, String> mapn;
     DefaultHttpClient httpClient;
     HttpPost httpPost;
     public JSONObject gettoken(String address,String token,String client_id,String client_secret,String redirect_uri,String grant_type) {
         // Making HTTP request
         try {
             // DefaultHttpClient
             httpClient = new DefaultHttpClient();
             httpPost = new HttpPost(address);
             params.add( new BasicNameValuePair( "code" , token));
             params.add( new BasicNameValuePair( "client_id" , client_id));
             params.add( new BasicNameValuePair( "client_secret" , client_secret));
             params.add( new BasicNameValuePair( "redirect_uri" , redirect_uri));
             params.add( new BasicNameValuePair( "grant_type" , grant_type));
             httpPost.setHeader( "Content-Type" , "application/x-www-form-urlencoded" );
             httpPost.setEntity( new UrlEncodedFormEntity(params));
             HttpResponse httpResponse = httpClient.execute(httpPost);
             HttpEntity httpEntity = httpResponse.getEntity();
             is = httpEntity.getContent();
         } catch (UnsupportedEncodingException e) {
             e.printStackTrace();
         } catch (ClientProtocolException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         }
         try {
             BufferedReader reader = new BufferedReader( new InputStreamReader(
                     is, "iso-8859-1" ), 8 );
             StringBuilder sb = new StringBuilder();
             String line = null ;
             while ((line = reader.readLine()) != null ) {
                 sb.append(line + "n" );
             }
             is.close();
             json = sb.toString();
             Log.e( "JSONStr" , json);
         } catch (Exception e) {
           e.getMessage();
             Log.e( "Buffer Error" , "Error converting result " + e.toString());
         }
         // Parse the String to a JSON Object
         try {
             jObj = new JSONObject(json);
         } catch (JSONException e) {
             Log.e( "JSON Parser" , "Error parsing data " + e.toString());
         }
         // Return JSON String
         return jObj;
     }
}

In the MainActivity we use WebViewClient to get the authorization code by loading the URL. The authorization URL should be in the form of

"https: //accounts.google.com/o/oauth2/auth?
scope=email%20profile&
redirect_uri=urn:ietf:wg:oauth: 2.0 :oob&
response_type=code&
client_id=CLIENT_ID"

After obtaining the Authorization code we are againg requesting Google for Access Token with the five parameters.”code,client_id,client_secret,redirect_uri,grant_type”. After obtaining the Access Token, Refresh Token,Expiration Time we are displayng it in TextView. You can use this Access Token to access Google APIs such as Maps,Translator etc..

MainActivity.java
package learn2crack.weboauth2;
import org.json.JSONException;
import org.json.JSONObject;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
   private static String CLIENT_ID = "842537427973-a381vrch0t5cgrgvtr02lik77a5bc8o7.apps.googleusercontent.com" ;
   //Use your own client id
   private static String CLIENT_SECRET = "EEOeMFHQpLtaHDU4Rr8k-l3N" ;
   //Use your own client secret
   private static String REDIRECT_URI= "http://localhost" ;
   private static String GRANT_TYPE= "authorization_code" ;
   private static String TOKEN_URL = "https://accounts.google.com/o/oauth2/token" ;
   private static String OAUTH_URL = "https://accounts.google.com/o/oauth2/auth" ;
   private static String OAUTH_SCOPE= "https://www.googleapis.com/auth/urlshortener" ;
   //Change the Scope as you need
   WebView web;
   Button auth;
   SharedPreferences pref;
   TextView Access;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
     super .onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
     pref = getSharedPreferences( "AppPref" , MODE_PRIVATE);
         Access =(TextView)findViewById(R.id.Access);
     auth = (Button)findViewById(R.id.auth);
     auth.setOnClickListener( new View.OnClickListener() {
       Dialog auth_dialog;
       @Override
       public void onClick(View arg0) {
         // TODO Auto-generated method stub
         auth_dialog = new Dialog(MainActivity. this );
         auth_dialog.setContentView(R.layout.auth_dialog);
         web = (WebView)auth_dialog.findViewById(R.id.webv);
         web.getSettings().setJavaScriptEnabled( true );
         web.loadUrl(OAUTH_URL+ "?redirect_uri=" +REDIRECT_URI+ "&response_type=code&client_id=" +CLIENT_ID+ "&scope=" +OAUTH_SCOPE);
         web.setWebViewClient( new WebViewClient() {
               boolean authComplete = false ;
               Intent resultIntent = new Intent();
               @Override
               public void onPageStarted(WebView view, String url, Bitmap favicon){
                super .onPageStarted(view, url, favicon);
               }
            String authCode;
               @Override
               public void onPageFinished(WebView view, String url) {
                   super .onPageFinished(view, url);
                   if (url.contains( "?code=" ) && authComplete != true ) {
                       Uri uri = Uri.parse(url);
                       authCode = uri.getQueryParameter( "code" );
                       Log.i( "" , "CODE : " + authCode);
                       authComplete = true ;
                       resultIntent.putExtra( "code" , authCode);
                       MainActivity. this .setResult(Activity.RESULT_OK, resultIntent);
                       setResult(Activity.RESULT_CANCELED, resultIntent);
                       SharedPreferences.Editor edit = pref.edit();
                       edit.putString( "Code" , authCode);
                     edit.commit();
                       auth_dialog.dismiss();
                       new TokenGet().execute();
                      Toast.makeText(getApplicationContext(), "Authorization Code is: " +authCode, Toast.LENGTH_SHORT).show();
                   } else if (url.contains( "error=access_denied" )){
                       Log.i( "" , "ACCESS_DENIED_HERE" );
                       resultIntent.putExtra( "code" , authCode);
                       authComplete = true ;
                       setResult(Activity.RESULT_CANCELED, resultIntent);
                     Toast.makeText(getApplicationContext(), "Error Occured" , Toast.LENGTH_SHORT).show();
                       auth_dialog.dismiss();
                   }
               }
           });
         auth_dialog.show();
         auth_dialog.setTitle( "Authorize Learn2Crack" );
         auth_dialog.setCancelable( true );
       }
     });
   }
    private class TokenGet extends AsyncTask<String, String, JSONObject> {
           private ProgressDialog pDialog;
           String Code;
          @Override
          protected void onPreExecute() {
              super .onPreExecute();
              pDialog = new ProgressDialog(MainActivity. this );
              pDialog.setMessage( "Contacting Google ..." );
              pDialog.setIndeterminate( false );
              pDialog.setCancelable( true );
              Code = pref.getString( "Code" , "" );
              pDialog.show();
          }
          @Override
          protected JSONObject doInBackground(String... args) {
              GetAccessToken jParser = new GetAccessToken();
              JSONObject json = jParser.gettoken(TOKEN_URL,Code,CLIENT_ID,CLIENT_SECRET,REDIRECT_URI,GRANT_TYPE);
              return json;
          }
           @Override
           protected void onPostExecute(JSONObject json) {
               pDialog.dismiss();
               if (json != null ){
                try {
               String tok = json.getString( "access_token" );
             String expire = json.getString( "expires_in" );
             String refresh = json.getString( "refresh_token" );
                  Log.d( "Token Access" , tok);
                  Log.d( "Expire" , expire);
                  Log.d( "Refresh" , refresh);
                    auth.setText( "Authenticated" );
                    Access.setText( "Access Token:" +tok+ "nExpires:" +expire+ "nRefresh Token:" +refresh);
           } catch (JSONException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
           }
                     } else {
                Toast.makeText(getApplicationContext(), "Network Error" , Toast.LENGTH_SHORT).show();
                pDialog.dismiss();
            }
           }
      }
}

Creating Manifest

We need the following permission for our Application.

android.permission.INTERNET
AndroidManifest.xml
<? xml version = "1.0" encoding = "utf-8" ?>
< manifest xmlns:android = "http://schemas.android.com/apk/res/android"
     package = "learn2crack.weboauth2"
     android:versionCode = "1"
     android:versionName = "1.0" >
     < uses-sdk
         android:minSdkVersion = "8"
         android:targetSdkVersion = "17" />
     < uses-permission android:name = "android.permission.INTERNET" />
     < application
         android:allowBackup = "true"
         android:icon = "@drawable/ic_launcher"
         android:label = "@string/app_name"
         android:theme = "@style/AppTheme" >
         < activity
             android:name = "learn2crack.weboauth2.MainActivity"
             android:label = "@string/app_name" >
             < intent-filter >
                 < action android:name = "android.intent.action.MAIN" />
                 < category android:name = "android.intent.category.LAUNCHER" />
             </ intent-filter >
         </ activity >
     </ application >
</ manifest >

Screenshots

Android performing OAuth2 Authorization using WebView Android performing OAuth2 Authorization using WebView Android performing OAuth2 Authorization using WebView

Any questions comment here


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值