Sample Code For Mobile Apps: A Particular Technique
Sample Code For Mobile Apps: A Particular Technique
1. Introduction
Relying parties may also want to develop an mobile App (on Android or iOS) to use the resources on their si
etc. Such mobile Apps usually use protocols like OAuth to get the user’s authentication via tokens and use th
the detailes of implementing a particular technique for the iphone and Android.
2. Basic workflow
Workflow of a typical user resource retrieval includes:
Login
User login into the RP site (with federated login or legacy login). The RP site ask user’s permission fo
and finish the login process.
Get token
The RP site sends the token back to the mobile App, and the mobile App detects that the RP site has
The mobile App fetch the token.
Retrieve data
The mobile App uses the token to call the RP’s web service API to retrieve the data.
3. Sample code and key technologies
3.1. iOS
The iOS provides both the default Safari browser and the UIWebView component for mobile Apps to launch
browser is a stand-alone application which is very hard to communicate with the App to deliver the token. Th
browser, and it is compiled as part of the mobile App, so it is convenient to access the UIWebView’s page tit
login/authenticate process.
(1) Create the UIWebView page in InterfaceBuilder
Create a new UIViewController and drag the UIWebView component onto it in InterfaceBuilder. Add some n
Note that in the above sample code, we did several key steps.
1. We setup the delegate for which we will call back to user code when we have to token
2. Set the UIWebView’s delegate to this class so that it will call back the webViewDidFinishLoad when t
3. We extract the domain string from the login URL because we will use this domain to extract the token
- (void)webViewDidFinishLoad:(UIWebView *)theWebView
{
NSString* token = [self getTokenFromCookie];
if (token != nil) {
[self.delegate gotToken:token];
[self.navigationController popViewControllerAnimated:YES];
}
}
Note that the “webViewDidFinishLoad” is a delegate function that UIWebView calls when it finish loading any
user’s authorized token, so we have to check if the token is already in the cookies and if so we will close the
main page.
After getting the token, we could use NSURLConnection to retrieve the data.
// Put the following line in the place where the user data retrieval begins.
NSURLConnection *aConnection = [NSURLConnection connectionWithRequest:[NSURL
delegate:self];
3.2. Android
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Start the WebViewActivity to handle the authentication.
case R.id.login:
Intent intent = new Intent(this, WebViewActivity.class);
intent.setData(Uri.parse(YOUR_AUTHENTICATION_ENDPOINT));
startActivityForResult(intent, 0);
return true;
// Exit.
case R.id.exit:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
The Android os provides a default web browser. Since the web browser is a stand-alone application and only
is difficult to get the OAuth token from it. The Android os also provides a widget called WebView, which allow
such as page title, cookies etc. In our practice, we choose WebView to do the work.
(1) Create the WebView activity
The activity is simple, which only contains a WebView widget.
public class WebViewActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Allow the title bar to show loading progress.
requestWindowFeature(Window.FEATURE_PROGRESS);
Second, it’s always a good practice to show the user which page is being viewed and whether the page is lo
WebViewClient to add these functions.
webview.setWebChromeClient(new WebChromeClient() {
// Show loading progress in activity's title bar.
@Override
public void onProgressChanged(WebView view, int progress) {
setProgress(progress * 100);
}
});
webview.setWebViewClient(new WebViewClient() {
// When start to load page, show url in activity's title bar
@Override
public void onPageStarted(WebView view, String url,
Bitmap favicon) {
setTitle(url);
}
});
@Override
public void onPageFinished(WebView view, String url) {
CookieSyncManager.getInstance().sync();
// Get the cookie from cookie jar.
String cookie = CookieManager.getInstance().getCookie(url);
if (cookie == null) {
return;
}
// Cookie is a string like NAME=VALUE [; NAME=VALUE]
String[] pairs = cookie.split(";");
for (int i = 0; i < pairs.length; ++i) {
String[] parts = pairs[i].split("=", 2);
// If token is found, return it to the calling activity.
if (parts.length == 2 &&
parts[0].equalsIgnoreCase("oauth_token")) {
Intent result = new Intent();
result.putExtra("token", parts[1]);
setResult(RESULT_OK, result);
finish();
}
}
}
});
If the site delivers the token by page title, you can get the title string by WebView.getTitle(), and extract the t
After the WebViewActivity destroys itself, the workflow is return to the calling activity. Since the WebViewAct
onActivityResult() callback will be called. Here’s the example:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
switch (requestCode) {
case 0:
if (resultCode != RESULT_OK || data == null) {
return;
}
// Get the token.
String token = data.getStringExtra("token");
if (token != null) {
/* Use the token to access data */
}
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
A lot of sites asks the user whether to remember the login state. If the user chooses to remember, the next t
login. This is supported by most web browsers. If you want the WebViewActivity has the same function, you
First, when you create your main activity, create a CookieSyncManager with the application context also.
CookieSyncManager.createInstance(getApplicationContext());
Then, in your WebViewActivity, you can start the sync process when WebViewActivity is resumed and stop t
another thread to sync the cookie between RAM and permanent storage periodically. You can also force the
in WebViewClient.onPageFinshed().
@Override
protected void onPause() {
super.onPause();
CookieSyncManager.getInstance().stopSync();
}
@Override
protected void onResume() {
super.onResume();
CookieSyncManager.getInstance().startSync();
}