Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Android Quickstart #2415

Merged
merged 16 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 8 additions & 23 deletions DocsDevREADME.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,31 +48,16 @@ Here are some guidelines to follow when writing documentation (everything under
```
egrep '^[=]+ ' site/docs/v1/tech/doc.adoc |sed 's/=//' |sed 's/=/*/g'|sed 's/* /* <</'|sed 's/$/>>/'
```
- We currently use [FontAwesome v5](https://fontawesome.com/v5/search?m=free) to render icons, so you can use them to refer to UI buttons, like this:
- In Markdown:
```markdown
<i/>{:.ui-button .green .fa .fa-plus}
<i/>{:.ui-button .green .fa .fa-search}
<i/>{:.ui-button .blue .fa .fa-edit}
<i/>{:.ui-button .blue .fa .fa-save}
<i/>{:.ui-button .purple .fas .fa-user}
<i/>{:.ui-button .purple .fa .fa-key}
<i/>{:.ui-button .gray .fa .fa-minus-circle}
<i/>{:.ui-button .red .fa .fa-trash-alt}
```
- In AsciiDoc:
```asciidoc
icon:plus[role=ui-button green,type=fas]
icon:search[role=ui-button green,type=fas]
icon:edit[role=ui-button blue,type=fas]
icon:save[role=ui-button blue,type=fas]
icon:user[role=ui-button purple,type=fas]
icon:key[role=ui-button purple,type=fa]
icon:minus-circle[role=ui-button gray,type=fa]
icon:trash-alt[role=ui-button red,type=fa]
- We currently use [FontAwesome v6](https://fontawesome.com/) to render icons, so you can use them to refer to UI buttons, like this:
```jsx
<IconButton icon="edit" color="blue" />
<IconButton icon="copy" color="purple" />
<IconButton icon="search" color="green" />
<IconButton icon="minus-circle" color="gray" />
<IconButton icon="trash" color="red" />
```

![icons](https://github.com/FusionAuth/fusionauth-site/assets/1877191/9fd29e3d-c81a-498c-9b82-135f44a7c545)
![icons](https://github.com/FusionAuth/fusionauth-site/assets/1877191/719bffe8-2a54-41a2-a339-b3afeda8d499)


### Including files
Expand Down
56 changes: 56 additions & 0 deletions astro/src/components/IconButton.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
interface Props {
icon: string;
color?: 'blue' | 'green' | 'red' | 'gray' | 'purple';
}

const {icon, color = 'blue'} = Astro.props;

let className = 'fa-' + String(icon).replaceAll(' ', '-');
switch (color) {
case 'blue':
case 'green':
case 'red':
case 'gray':
case 'purple':
className += ' btn-icon-' + color;
break;
}
---
<i class={"btn-icon fa fa-duotone " + className}></i>

<style>
:global(.fa-duotone::before) {
--fa-primary-color: #cbd5e1;
}
.btn-icon {
--color: #fff;
padding: 5px 7px 7px;
border-radius: 3px;
background-color: var(--color);
border: 1px solid var(--color);
}
.btn-icon:after {
color: #fff;
opacity: 1;
}
.btn-icon.btn-icon-blue {
--color: #3998db;
}
.btn-icon.btn-icon-green {
--color: #0bb796;
}
.btn-icon.btn-icon-red {
--color: #ee3e54;
}
.btn-icon.btn-icon-purple {
--color: #34485e;
}
.btn-icon.btn-icon-gray {
border-color: #bfbfbf;
--color: #f7f7f7;
}
.btn-icon.btn-icon-gray:after {
color: #262626;
}
</style>
224 changes: 224 additions & 0 deletions astro/src/content/quickstarts/quickstart-android-java-native.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
---
title: Android Java
description: Quickstart integration of a Java-based Android app with FusionAuth
navcategory: getting-started
prerequisites: Android Studio, Git
section: native
technology: Android
language: Java
icon: /img/icons/android.svg
faIcon: fa-android
color: indigo
cta: EmailListCTA
---
import Aside from '../../components/Aside.astro';
import LoginAfter from '../../diagrams/quickstarts/login-after-native.astro';
import LoginBefore from '../../diagrams/quickstarts/login-before-native.astro';
import IconButton from '../../components/IconButton.astro';
import RemoteCode from '../../components/RemoteCode.astro';

In this quickstart you are going to build an Android app with Java and integrate it with FusionAuth.
You'll be building it for [ChangeBank](https://www.youtube.com/watch?v=CXDxNCzUspM), a global leader in converting dollars into coins.
It'll have areas reserved for users who have logged in as well as public facing sections.

The docker compose file and source code for a complete application are available at
[https://github.com/FusionAuth/fusionauth-quickstart-java-android-native](https://github.com/FusionAuth/fusionauth-quickstart-java-android-native).

## Prerequisites

- [Android Studio](https://developer.android.com/studio): The official IDE for Android will help you develop and install necessary tools to set it up.
- There, you need to [install at least JDK 17](https://developer.android.com/build/jdks).
- [Git](https://git-scm.com/site): You'll use it to clone the base repository.
- [Docker](https://www.docker.com): The quickest way to stand up FusionAuth. (There are [other ways](/docs/v1/tech/installation-guide/)).

This app was built on top of [AppAuth](https://github.com/openid/AppAuth-Android), which is an open source client SDK for communicating with OAuth 2.0 and OpenID Connect providers. AppAuthisupports Android API 16 (Jellybean) and above.

## General Architecture

While this sample application doesn't have login functionality without FusionAuth, a more typical integration will replace an existing login system with FusionAuth.

In that case, the system might look like this before FusionAuth is introduced.

<LoginBefore/>

The login flow will look like this after FusionAuth is introduced.

<LoginAfter/>

In general, you are introducing FusionAuth in order to normalize and consolidate user data. This helps make sure it is consistent and up-to-date as well as offloading your login security and functionality to FusionAuth.

## Getting Started

In this section, you'll get FusionAuth up and running and use `git` to create a new application.

### Clone the Code

First off, grab the code from the repository and change into that directory.

```shell
git clone https://github.com/FusionAuth/fusionauth-quickstart-java-android-native.git
cd fusionauth-quickstart-java-android-native
```

### Run FusionAuth via Docker

In the root directory of the repo you'll find a Docker compose file (`docker-compose.yml`) and an environment variables configuration file (`.env`). Assuming you have Docker installed on your machine, you can stand up FusionAuth up on your machine with:

```
docker compose up -d
```

Here you are using a bootstrapping feature of FusionAuth, called [Kickstart](/docs/v1/tech/installation-guide/kickstart). When FusionAuth comes up for the first time, it will look at the `kickstart/kickstart.json` file and configure FusionAuth to a certain initial state.

<Aside type="note">
If you ever want to reset the FusionAuth system, delete the volumes created by docker compose by executing `docker compose down -v`, then re-run `docker compose up -d`.
</Aside>

FusionAuth will be initially configured with these settings:

* Your client Id is `e9fdb985-9173-4e01-9d73-ac2d60d1dc8e`.
* Your client secret is `super-secret-secret-that-should-be-regenerated-for-production`.
* Your example username is `[email protected]` and the password is `password`.
* Your admin username is `[email protected]` and the password is `password`.
* The base URL of FusionAuth `http://localhost:9011/`.

### Expose FusionAuth Instance

To make sure your local FusionAuth instance is accessible to your Android app, you need to [expose it to the Internet](/docs/v1/tech/developer-guide/exposing-instance). Write down the URL ngrok gave you as you'll need it soon.

### Configure FusionAuth Instance

Now that you have [exposed your instance](#expose-fusionauth-instance), you need to update the Tenant issuer to make sure it matches the given address.

Log into the [FusionAuth admin UI](http://localhost:9011/admin), browse to `Tenants` in the sidebar, click <IconButton icon="edit" color="blue" /> on the **Default** tenant to edit it. Paste the complete address _(with protocol and domain)_ you copied from ngrok into the `Issuer` field (e.g. `https://6d1e-2804-431-c7c9-739-4703-98a7-4b81-5ba6.ngrok-free.app`). Save the application by clicking the <IconButton icon="save" color="blue" /> icon in the top right corner.

Navigate to `Applications` and click <IconButton icon="edit" color="blue" /> on the **Example Android App** application. Click on the `JWT` tab, change both `Access token signing key` and `Id token signing key` to `Auto generate a new key on save...` and save the application.

<Aside type="note">
You must create new keys after modifying the `Tenant` because the `Issuer` field is embedded in the key.
</Aside>

### Create your Android App

Now you are going to create an Android app. While this section builds a simple Android app on top of the [AppAuth demo app](https://github.com/openid/AppAuth-Android), you can use the same configuration to integrate your existing app with FusionAuth.

```shell
git clone https://github.com/FusionAuth/openid-AppAuth-Android.git
cd openid-AppAuth-Android
```

Start by removing some unused files:

```shell
rm app/java/io/fusionauth/app/BrowserSelectionAdapter.java
rm app/res/layout/browser_selector_layout.xml
```

Change the package namespace in `app/build.gradle`. You can replace the entire file with below contents.

<RemoteCode url="https://raw.githubusercontent.com/FusionAuth/fusionauth-quickstart-java-android-native/main/complete-application/app/build.gradle"
lang="groovy"/>

Replace `app/AndroidManifest.xml` as well.

<RemoteCode url="https://raw.githubusercontent.com/FusionAuth/fusionauth-quickstart-java-android-native/main/complete-application/app/AndroidManifest.xml"
lang="xml"/>

## Authentication

We'll use the [AppAuth Library](https://github.com/openid/AppAuth-Android), which simplifies integrating with FusionAuth and creating a secure web application.

### Configure AppAuth

Modify `app/res/raw/auth_config.json` to use the values provisioned by Kickstart. Update the `discovery_uri` value; change `https://[YOUR-NGROK-MAIN-DOMAIN]` to the URL you wrote when [exposing your instance](#expose-fusionauth-instance).

<RemoteCode url="https://raw.githubusercontent.com/FusionAuth/fusionauth-quickstart-java-android-native/main/complete-application/app/res/raw/auth_config.json"
lang="json"/>

### Change Activities

An [Activity](https://developer.android.com/guide/components/activities/intro-activities) is a screen for your app, combining the User Interface as well as the logic to handle it. Start by changing the login activity layout at `app/res/layout/activity_login.xml`. Replace it with the below XML.

<RemoteCode url="https://raw.githubusercontent.com/FusionAuth/fusionauth-quickstart-java-android-native/main/complete-application/app/res/layout/activity_login.xml"
lang="xml"/>

Now modify login activity logic by replacing `app/java/io/fusionauth/app/LoginActivity.java` with this code.

<RemoteCode url="https://raw.githubusercontent.com/FusionAuth/fusionauth-quickstart-java-android-native/main/complete-application/app/java/io/fusionauth/app/LoginActivity.java"
lang="java"/>

Update the main screen layout in the file `app/res/layout/activity_token.xml`.

<RemoteCode url="https://raw.githubusercontent.com/FusionAuth/fusionauth-quickstart-java-android-native/main/complete-application/app/res/layout/activity_token.xml"
lang="xml"/>

And finally, change the main screen logic by replacing the content of `app/java/io/fusionauth/app/TokenActivity.java` with the below.

<RemoteCode url="https://raw.githubusercontent.com/FusionAuth/fusionauth-quickstart-java-android-native/main/complete-application/app/java/io/fusionauth/app/TokenActivity.java"
lang="java"/>

## App Customization

In this section, you'll update the look and feel of your native application to match the ChangeBank banking styling.

### Change Colors and Strings

Change the application colors in `app/res/values/colors.xml` to the ones used by Changebank.

<RemoteCode url="https://raw.githubusercontent.com/FusionAuth/fusionauth-quickstart-java-android-native/main/complete-application/app/res/values/colors.xml"
lang="xml"/>

Modify strings shown in the user interface by updating `app/res/values/strings.xml`.

<RemoteCode url="https://raw.githubusercontent.com/FusionAuth/fusionauth-quickstart-java-android-native/main/complete-application/app/res/values/strings.xml"
lang="xml"/>

### Add Styling

Now, add image assets to make this look like a real application with the following shell commands.

```shell
curl -o app/res/drawable/changebank.png https://raw.githubusercontent.com/FusionAuth/fusionauth-quickstart-java-android-native/main/complete-application/app/res/drawable/changebank.png
curl -o app/res/mipmap-hdpi/ic_launcher.png https://raw.githubusercontent.com/FusionAuth/fusionauth-quickstart-java-android-native/main/complete-application/app/res/mipmap-hdpi/ic_launcher.png
curl -o app/res/mipmap-hdpi/ic_launcher.png https://raw.githubusercontent.com/FusionAuth/fusionauth-quickstart-java-android-native/main/complete-application/app/res/mipmap-hdpi/ic_launcher.png
curl -o app/res/mipmap-mdpi/ic_launcher.png https://raw.githubusercontent.com/FusionAuth/fusionauth-quickstart-java-android-native/main/complete-application/app/res/mipmap-mdpi/ic_launcher.png
curl -o app/res/mipmap-xhdpi/ic_launcher.png https://raw.githubusercontent.com/FusionAuth/fusionauth-quickstart-java-android-native/main/complete-application/app/res/mipmap-xhdpi/ic_launcher.png
curl -o app/res/mipmap-xxhdpi/ic_launcher.png https://raw.githubusercontent.com/FusionAuth/fusionauth-quickstart-java-android-native/main/complete-application/app/res/mipmap-xxhdpi/ic_launcher.png
curl -o app/res/mipmap-xxxhdpi/ic_launcher.png https://raw.githubusercontent.com/FusionAuth/fusionauth-quickstart-java-android-native/main/complete-application/app/res/mipmap-xxxhdpi/ic_launcher.png
```

Once you've created these files, you can test the application out.

## Run the App

You can either [connect a hardware device](https://developer.android.com/studio/run/device) or create an Android Virtual Device to run the [Android Emulator](https://developer.android.com/studio/run/emulator)

[Build and run the app](https://developer.android.com/studio/run/) following Android Studio guidelines.

## Next Steps

This quickstart is a great way to get a proof of concept up and running quickly, but to run your application in production, there are some things you're going to want to do.

### FusionAuth Customization

FusionAuth gives you the ability to customize just about everything with the user's experience and your application's integration. This includes
* [Hosted pages](/docs/v1/tech/themes/) such as login, registration, email verification, and many more
* [Email templates](/docs/v1/tech/email-templates/email-templates)
* [User data and custom claims in access token JWTs](/articles/tokens/jwt-components-explained)

### Security
* Implement refresh tokens using [AppAuth](https://github.com/openid/AppAuth-Android)
* You may want to customize the [token expiration times and policies](/docs/v1/tech/oauth/#configure-application-oauth-settings) in FusionAuth
* Choose [password rules](/docs/v1/tech/core-concepts/tenants#password) and a [hashing algorithm](/docs/v1/tech/reference/password-hashes) that meet your security needs

### Tenant and Application Management
* Model your application topology using [Applications](/docs/v1/tech/core-concepts/applications), [Roles](/docs/v1/tech/core-concepts/roles), [Groups](/docs/v1/tech/core-concepts/groups), [Entities](/docs/v1/tech/core-concepts/groups), and more
* Set up [MFA](/docs/v1/tech/guides/multi-factor-authentication), [Social login](/docs/v1/tech/identity-providers/), and/or [SAML](/docs/v1/tech/identity-providers/samlv2/) integrations
* Integrate with external systems using [Webhooks](/docs/v1/tech/events-webhooks/), [SCIM](/docs/v1/tech/core-concepts/scim), and [Lambdas](/docs/v1/tech/lambdas/)

## Troubleshooting

* I can't log in

Make sure you have the right values at `app/res/raw/auth_config.json`. Double-check the `Issuer` in the **Tenant** to make sure it matches the public URL that FusionAuth is running at.

27 changes: 27 additions & 0 deletions astro/src/diagrams/quickstarts/login-after-native.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
import Diagram from "../../components/mermaid/Diagram.astro";
const { alt = "Request flow during login after FusionAuth" } = Astro.props;

//language=Mermaid
const diagram = `
sequenceDiagram
participant User
participant App as Mobile Application
participant FusionAuth
participant API as API Server

User ->> App : View Homescreen
User ->> App : Click Login Button (to FusionAuth)
User ->> FusionAuth : View Login Form
FusionAuth ->> User : Show Login Form
User ->> FusionAuth : Fill Out and Submit Login Form
FusionAuth ->> FusionAuth : Authenticates User
FusionAuth ->> User: Go to Redirect URI
User ->> App: Request the Redirect URI
App ->> FusionAuth : Is User Authenticated?
FusionAuth ->> App : User is Authenticated
App ->> API : Retrieve User Data
API ->> App : Return User Data
App ->> User : Display User's Account or Other Info`;
---
<Diagram code={diagram} alt={alt}/>
2 changes: 1 addition & 1 deletion astro/src/diagrams/quickstarts/login-after.astro
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
import Diagram from "../../components/mermaid/Diagram.astro";
const { alt } = Astro.props;
const { alt = "Request flow during login after FusionAuth" } = Astro.props;

//language=Mermaid
const diagram = `
Expand Down
22 changes: 22 additions & 0 deletions astro/src/diagrams/quickstarts/login-before-native.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
import Diagram from "../../components/mermaid/Diagram.astro";
const { alt = "Request flow during login before FusionAuth" } = Astro.props;

//language=Mermaid
const diagram = `
sequenceDiagram
participant User
participant App as Mobile Application
participant API as API Server

User ->> App : View Homescreen
User ->> App : Click Login Button
App ->> User : Show Login Form
User ->> App : Fill Out and Submit Login Form
App ->> API : Is User Authenticated?
API ->> App : User is Authenticated
App ->> API : Retrieve User Data
API ->> App : Return User Data
App ->> User : Display User's Account or Other Info`;
---
<Diagram code={diagram} alt={alt}/>
2 changes: 1 addition & 1 deletion astro/src/diagrams/quickstarts/login-before.astro
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
import Diagram from "../../components/mermaid/Diagram.astro";
const { alt } = Astro.props;
const { alt = "Request flow during login before FusionAuth" } = Astro.props;

//language=Mermaid
const diagram = `
Expand Down
Loading