Handle Django Api Authentication in Android Cordova App

Handle Django Api Authentication in Android Cordova App

One main consideration of an app is how to handle api authentication. For an android cordova app with django powered backend, you need to deal with two cases: native part and cordova part.

Django Authentication Mechanism

Most likely, you will use django session, which save a sessionid in cookies instead of data itself.

The figure below shows cookies of django site. You can see there is a name sessionid in the last line. Django use this sessionid to recognise user status.

enter image description here

where is the sessionid come from

So where this sessionid come from? Suppose you have an api for use to login, for example http://127.0.0.1:8000/api/user/login/, which use following codes presented in django website to login user.

def login_view(request):
    username = request.POST['username']
    password = request.POST['password']
    user = authenticate(username=username, password=password)
    if user is not None:
        if user.is_active:
            login(request, user)
            # Redirect to a success page.
        else:
            # Return a 'disabled account' error message
            ...
    else:
        # Return an 'invalid login' error message.
        ...

After you call the login api, you can see the sessionid cookie in response header, which is exactly what we need.

enter image description here

what to do with sessionid

The sessionid is used to recognise user. One common situation is that you want your api only available to user who has logged in. In such case, you need to pass the sessionid in every api request(header) in order to do authentication.

Retrieve Sessionid From Response Header

In case we need the sessionid, we have to get it first. If you use apache cordova for your whole application, then you don't need to do anything, the cordova webview should be able to handle cookie for you. But if your android app combines native with cordova, then you may need to do some stuff to pass the sessionid from native to cordova and vice versa.

In my application, the login page is native, so I need to retrieve the sessionid in native android code. The code snippet below demonstrate such process. What it does is for loop the api response header and find the sessionid out(I use volley for httpclient). Note that such process should be performed in login api.

private void findAndSaveSessionString(NetworkResponse response) {
    for (int i = 0; i < response.apacheHeaders.length; i++) {
        String key = response.apacheHeaders[i].getName();
        if (key.equals("Set-Cookie")) {
            String value = response.apacheHeaders[i].getValue();
            String subKey = "";
            try {
                subKey = value.split(";")[0].split("=")[0];
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            if (subKey.equals("sessionid")) {
                Utils.setSettionString(mContext, value);
            }
        }
    }
}

Pass Sessionid to Cordova Webview

In previous post, I mention how to Embed Cordova Webview in Android Native App. In order to pass the sessionid from native to cordova webview, we need to use the setCookie method of cookieManager. To get the cookieManager, we can use getCookieManager method of SystemWebViewEngine. Below is the modified version TestCordovaWithLayoutActivity that handled sessionid passing.

public class TestCordovaWithLayoutActivity extends CordovaActivity {
    ...
    @Override
    protected CordovaWebView makeWebView() {
        SystemWebView webView = (SystemWebView)findViewById(R.id.cordovaWebView);
        SystemWebViewEngine engine = new SystemWebViewEngine(webView);
        setCookie(engine);
        return new CordovaWebViewImpl(engine);
    }

    private void setCookie(SystemWebViewEngine engine) {
        SharedPreferences preferences = this.getSharedPreferences(Configurations.COOKIE_PREFERENCE, 0);
        String sessionId = preferences.getString(Configurations.COOKIE_SESSIONID_KEY, null);
        if (sessionId != null) {
          engine.getCookieManager().setCookie(Configurations.getDomain(), sessionId);
        }
    }
    ...
}

After this setting, the cordova webview should be able to provide the sessionid in its every api request. Job done !

Currently unrated

Comments

ADDRESS

  • Email: jimmykobe1171@126.com
  • Website: www.catharinegeek.com