-3

I have sample native android app. User creates a profile for the application that user wants to access. Based on application set up, user will be redirected to a particular URL in browser for authentication OR shown a login screen in native app. If user is redirected to an URL in browser ( i am using a webview), I want to send the response back to native app about the status of authentication. How do I do that? How can I add listener to intent which is starting BrowserActivity?

yogsma
  • 10,142
  • 31
  • 97
  • 154
  • I don't think that web browsers return responses to application that provided URL. Maybe you should consider using WebView, there is more control. – Damian Petla Aug 25 '14 at 16:29
  • I am using webview, now the issue is once the user is redirected to URL in webview and user authenticates successfully, how do I know that user has finished with authentication? – yogsma Aug 26 '14 at 19:14
  • Did you try to set [WebViewClient](http://developer.android.com/reference/android/webkit/WebViewClient.html) for your WebView? It provides handful callbacks that let you control WebView – Damian Petla Aug 27 '14 at 08:35
  • Yeah, but there is nothing based on finishing authentication. Once the user launches the webview, a login form is displayed and user provides the credentials and after this it should take me back to native app. It is not happening. – yogsma Aug 27 '14 at 19:24
  • You can define the url pattern in AndroidManifest.xml which causes the specific url action to be caught and received inside Activity as Intent. I've done this once as part of the old Foursquare Oauth. Now I don't have time to digg it up, but if you still don't find the solution I can check later. – Luka Bradeško Sep 03 '14 at 16:25

6 Answers6

4

Look for something consistent in the server's response to the authentication attempt that the WebView can detect and branch on.

For example, Google OAuth puts the results in the <title> element of the HTML response, so you parse that and return a response to the calling activity in a WebChromeClient onReceivedTitle handler:

public class MyChrome extends WebChromeClient {
    public void onReceivedTitle(WebView view, String title) {
        final Intent i = new Intent();
        if (title.startsWith("Denied")) {
            i.putExtra("auth2code", "");
            setResult(RESULT_OK, i);
            finish();
        } else if (title.contains("code=")) {
            final String[] stuff = title.split("=");
            if (stuff.length > 1) {
                auth2code = stuff[1];
                i.putExtra("auth2code", auth2code);
            } else {
                i.putExtra("auth2code", "");
            }
            setResult(RESULT_OK, i);
            finish();
        }
    }
}

(In onCreate you need to say something like webView.setWebChromeClient(new MyChrome());)

This example shows the basic method, but it has to be modified based on how any given service actually responds to an authentication attempt.

x-code
  • 2,940
  • 1
  • 18
  • 19
2

To do this, you first build you WebView client in an activity, as you've mentioned.

Next, start the activity with startActivityForResult so that you can get the data you need back from the WebView client.

Next, in the webview Activity, setup a Javascript bridge:

https://labs.mwrinfosecurity.com/blog/2014/06/12/putting-javascript-bridges-into-android-context/

Then you can use Javascript to pass data from resulting web pages to your Activity. Depending on the data passed in, you could have a method that will return whatever values you want from the web page, forms, etc.

Authentication status is one thing that you can pass, but with Javascript bridge, you can do a lot more.

Jim
  • 10,172
  • 1
  • 27
  • 36
2

I used JSON to communicate the native android app with the server.

/**
 * Represents an asynchronous login/registration task used to authenticate
 * the user.
 */
 public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {

    @Override
    protected Boolean doInBackground(Void... params) {

        //Comunicate HttpClient object to communicate with the server
        HttpClient comunicacion = new DefaultHttpClient();

        //Create a new POST request with the URL of the server service
        HttpPost peticion = new HttpPost(URL);

        try 
        {
            String idEnviado = String.valueOf(System.currentTimeMillis());
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("action", "login"));
            nameValuePairs.add(new BasicNameValuePair("id", idEnviado));
            nameValuePairs.add(new BasicNameValuePair("email", mEmail));
            nameValuePairs.add(new BasicNameValuePair("password", mPassword));

            peticion.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            peticion.setHeader("Accept", "application/json");

            //Execute request and obtain response as a string
            HttpResponse respuesta = comunicacion.execute(peticion);
            String respuestaString = EntityUtils.toString(respuesta.getEntity());

            //JSONObject to read the attributes of the response
            JSONObject respuestaJSON = new JSONObject(respuestaString);

            //The server answers authentication is valid
            if (respuestaJSON.get("result").equals("true"))
            {   
                idUsuario = respuestaJSON.getString("userId");
                insertarUsuarioEnBD(idUsuario);
                return true;
            }
            else
            {
                return false;
            }
        } catch(Exception e) {
            Log.e("Error", "Error in server response.", e);
        }
        return false;
    }

When you create a new app from eclipse at least for the 4.0.0 version or higher, it gives you the option of choosing a new LoginActivity, which is almost entirely implemented and shows you the correct way to authenticate in an Android App.

I hope this helps!

Kutyel
  • 8,575
  • 3
  • 30
  • 61
  • I will if that completely solves my problem. It has not solved my issue, but I awarded you the bounty points because your answer was close to what I am trying. – yogsma Sep 08 '14 at 19:48
1

WebViewClient.shouldOverrideUrlLoading is called when an URL is about to be loaded by a WebView. You can override this method and acts accordingly when user is redirected to a specified URL after authentication.

A simple example can be found here: https://github.com/nguyenhuy/buffer/blob/master/buffer/src/main/java/org/nguyenhuy/buffer/fragment/OAuthFragment.java

huy.nguyen
  • 454
  • 2
  • 9
1

In case authorization page it's your own web resource you also can use WebView callback thru web page JavaScript to Android as explained here: http://blog.objectgraph.com/index.php/2012/03/16/android-development-javascript-bridge-example-fully-explained/

and pass data back to native Android application from web page.

dasar
  • 5,321
  • 4
  • 24
  • 36
0

If you are using nodejs for your service, you can use res.send( {data: successfulLogin} ); Or something like this. And then parse it, use where you want.

Lazy
  • 1,807
  • 4
  • 29
  • 49