Monthly Archives: February 2022

You are here: Home . Archive

Getting Started with Amazon Cognito: Part 1

I first worked with Amazon Web Services (AWS) Cognito in 2018 while building a financial web app that was deeply tied to the AWS infrastructure. It made use of AWS lambas, AWS Dynamo DB, the API gateway and AWS Cognito to process data from banks and create a rewards platform for businesses. Cognito’s documentation then, as AWS’s documentation tends to be, was quite difficult to work through. I pieced together a usable solution but didn’t foresee Cognito and I meeting again.

Fast-forward a few weeks ago and I needed to evaluate both Cognito and Firebase as an authentication service to use for a powerful insurance web app. While it is almost 4 years since that fateful encounter with Cognito, the nightmares are still fresh, and I still bear the scars. I’d have loved to immediately call it for Firebase but I took a number of key technical factors into consideration and Cognito came out on top. So, we meet again, my old friend foe…

I went in, silently hoping Cognito had changed her ways. The joke was on me. Several days later, I realized Cognito might have only gotten worse (in documentation) over the years 🙂   

In case you’ve had similar challenges, here’s a high-level walk-through of how I went about implementing Cognito for a JS front-end [Vue.js] and a Django backend.

I’ll break this down into a series of articles:

  1. Implementing Cognito on the frontend
  2. Implementing Cognito on the backend and migrating your users (if you had an existing app)

To set the stage, it is quite useful to know [or get a refresher] on JSON web tokens (JWTs). To do that, check out this article

In it, you see that we follow the following steps:

  1. The application or client requests authorization to the authorization server, in this case Cognito. This is performed through one of the different authorization flows.
  2. When the authorization is granted, the authorization server [Cognito] returns an access token to the client application.
  3. The client application uses the access token when making all requests to the backend API

Based on this flow, you’d change your front-end to talk to AWS Cognito, retrieve a JWT and then from that point forward, use that JWT with all your API requests.

So basically, as you look at changing your app to start using Cognito, you need to do two things:

  • Change your frontend to retrieve a Cognito token on login, then use that token going-forward with every API call it makes.
  • Change your backend to retrieve the token given to it, verify it and grant access to the parts of the application the user can have access to.

Some extra steps you might consider doing on the frontend:

  • If the token expires, reach out to Cognito for a new one. Amazon’s documentation covers that here but this is a useful article as well. Alternatively, you can just logout the user so they need to re-login
  • Make it possible for users to register. When a user registers, register them with Cognito
  • Add the ability for a user to reset their password
  • Support Groups and custom user permissions

I called these steps optional because you have the option to use Cognito’s self-hosted UI to do them. It would save you lots of hours of coding time.

In the following articles, I’ll get into how to get into changing your frontend and your backend as well.

How to customize Android product flavour app name, strings, styles and the manifest

Android development has a powerful feature that allows you to modify an Android application and make it possible for it to be customized and deployed using a different look and functionality. Some examples where this might be useful:

  • White-labelling: This is where you have an application that you customise for each customer. For example, you have an eCommerce app but have different customers who would like to have their own version of that app. Also, you could have a ride-sharing app that you customise for your various customers
  • More commonly, you have a free version of your app but you’d like to create a paid version with more features

Just to re-iterate, for you who already has an existing app, depending on your strategy, Android flavours give you the option of increasing your income streams by customising the same app, and making it available for use by other customers.

That said, while this tutorial gives a really good introduction to what flavours are and how to get started with them, here, I’ll focus on the specifics of how to actually go about customising them in what I feel is a robust way.

Google’s documentation gives instructions on how to modify various aspects of the different flavours but I’ll get into specifically how to customise the following:

  1. The AndroidManifest.xml
  2. Specific Strings [Instead of feeling pressed to have to customise the entire strings.xml file]
  3. Styles

I’ll focus on the scenario where you’d like to customise just a subset – such as a subset of the strings you have in strings.xml – as opposed to the entire strings.xml file. One disadvantage of copying an entire AndroidManifest.xml or strings.xml is the repetition it introduces; if you need to change something, you might need to change it in multiple files. One of the principles of software engineering is Do Not Repeat Yourself (DRY). Let’s see how to do that.

Android has something called manifest placeholders, a pretty cool feature that will allow you to modify AndroidManifest.xml without needing to re-write the entire file. Here’s an example where we modify the app name per flavour.

Customize the AndroidManifest.xml per flavour

Change this in AndroidManifest.xml:

    <application
        android:label="@string/appLabel"

to:

<application
    android:label="${appLabel}"
    tools:replace="android:label"

${appLabel} is a manifest placeholder. Then, in your .build.gradle file, in the android section, modify the defaultConfig section to define the appLabel placeholder.

defaultConfig {
        manifestPlaceholders = [appLabel:"@string/app_name"]

In your flavours, you can define the manifest placeholder as well:

Specific strings

  flavorDimensions 'default'
    productFlavors {
        shopTillYouDrop {
            dimension = 'default'
            versionNameSuffix = '-styd'
            manifestPlaceholders = [appLabel:"@string/app_name_styd"]

This way, you can define app_name and app_name_styd in strings.xml and be able to translate it into various languages if need be. You can use the same technique to customise other aspects of the AndroidManifest.xml. Here’s how to use that technique to specify different themes.

 
    defaultConfig {
        manifestPlaceholders = [appLabel:"@string/app_name", appTheme:"@style/ShoppingTheme"]
}
appTheme:"@style/KanzuBankingTheme"]
 flavorDimensions 'default'
    productFlavors {
        shopTillYouDrop {
            dimension = 'default'
            versionNameSuffix = '-styd'
            manifestPlaceholders = [appLabel:"@string/app_name", appTheme:"@style/ShopTillYouDropAppTheme"]

You can see that with this technique, you won’t need multiple AndroidManifest.xml files.

Customize specific strings per flavour

Sometimes you need to have just a few strings in the entire strings.xml changed in your flavour. Android scans the res folder and picks strings from the files present. Because of this, move every string you’d like to customise into a different file e.g. strings_flavours.xml. This technique is mainly useful if you don’t think you’ll modify very many strings in strings.xml. Create strings_flavours.xml in src/main/res/values/. Make sure you remove all these strings from strings.xml.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="flavour_string_one">String Value</string>
    <string name="flavour_string_two">String value two</string>
</resources>

Now, you can simply create strings_flavours.xml in your flavour directories .e.g src/shopTillYouDrop/res/values and update it.

Customize styles

Lastly, you can create custom themes for each flavour. As I pointed out while customising AndroidManifest.xml, you can change the theme per flavour using the technique I showed above. Now, knowing that you have specified a different theme, all you need to do is create the new theme, make the default theme its parent theme then go ahead and customise any aspect of the custom theme you’ve created.

<resources>

    <!-- Shop till you drop Product Flavour custom theme. -->
    <style name="ShopTillYouDropAppTheme" parent="DefaultAppTheme">
        <item name="android:fontFamily">@font/opensans</item>
        <item name="buttonStyle">@style/ShopTillYouDroAppTheme.Button</item>
    </style>

    <!-- Base application theme. -->
    <style name="DefaultAppTheme" parent="MaterialAppTheme">
        <!-- Customize your theme here. -->
    </style>