OAuth 2.0 Support

Overview

UniWebView provides support for OAuth 2.0 authorization code flowopen in new window. It contains built-in support for several popular OAuth 2.0 providers by following their options, which are:

Service ProviderUniWebView Auth ClassProvider Documentation
GoogleUniWebViewAuthenticationFlowGoogleOAuth 2.0 for Mobile & Desktop Appsopen in new window
FacebookUniWebViewAuthenticationFlowFacebookManually Build a Login Flowopen in new window
TwitterUniWebViewAuthenticationFlowTwitterAuthenticationopen in new window
GitHubUniWebViewAuthenticationFlowGitHubAuthorizing OAuth Appsopen in new window
DiscordUniWebViewAuthenticationFlowDiscordOAuth2 in Discordopen in new window
LINEUniWebViewAuthenticationFlowLineLINE Login v2.1 API referenceopen in new window

Besides of them, UniWebView also a customizable common setup for any other services which provides a standard OAuth 2.0 code flow.

UniWebView follows the OAuth 2.0 standard and use a secure way to perform authentication. It supports both state verification and PKCEopen in new window challenge out-of-the-box, which simplifies your work a lot.

In this guide, we will cover both and show you how to have your users login to a service with OAuth 2.0.

All services names and trademarks are property of their respective owners in this guide.

Checking Availability

This feature is not available on all UniWebView supporting platforms. On Apple's devices, it only works on iOS 11, macOS 10.15 and later. On Android, it requires the similar environment as Safe Browsing Mode.

Target API Level higher than Android 11

On Android, if you set your Target API Level to Android 11 (30) or later, you need to add the correct intent query explicitly in your AndroidManifest.xml file, to follow the Package Visibilityopen in new window to add queries as a sub-node of the manifest tag:

<manifest>
  // ...

  </application>

  <queries>
    <intent>
      <action android:name="android.support.customtabs.action.CustomTabsService" />
    </intent>
  </queries>
</manifest>





 
 
 
 
 

Package Visibility from Android 11

If you are setting Target API Level higher than Android 11 (API Level 30), but not setting the queries in your AndroidManifest.xml, the OAuth 2.0 related APIs will not work expectedly on Android.

Runtime Checking

To check if OAuth 2.0 feature is available at runtime, call IsAuthenticationSupported like this:

if (UniWebViewAuthenticationSession.IsAuthenticationSupported) {
    // OAuth 2.0 code flow is available on current device.
}

This IsAuthenticationSupported property returns true on Android with customize tabs, iOS 11, macOS 10.15 and later. You should always check whether this feature is available before using it. Only continue to use OAuth 2.0 feature when this value is true. Otherwise, the authentication flow may not even start.

Built-In Providers

For built-in supported providers mentioned above, each provider has a dedicated class responsible for the authentication flow. In this guide, we are using GitHub for demonstration purpose. For other providers, most of the settings are the same. For the provider-specific settings, please refer to the API reference of each class to know more details.

Adding Component

We assumed that you have already created a GitHub App to follow this guide. If not yet, please refer to this official guideopen in new window to create one. We assume you have the following information for the app, and we will use them in this guide:

GitHub App FieldValue
Client IDIv1.1234567890abcdef
Client Secret1234567890abcdef1234567890abcdef
Callback URLauthhub://auth
Enable Device Flowfalse
Webhook - Activefalse
Request user authorization (OAuth) during installationfalse

* The values here are only for demonstration purpose. In your implementation, replace them to the actual values of your app.

To get started, adding the UniWebViewAuthenticationFlowGitHub component to any of your game object in the scene. The easiest way is clicking the "Add Component" button in the Inspector, and search for "github":

Setting Properties

Next, fill the necessary values of your app to the added UniWebViewAuthenticationFlowGitHub component. In this example, we need to set "Client Id", "Client Secret" and "Callback Url":

You may find two common options for all OAuth providers: "Authorize On Start" and "Private Mode". We will cover them below soon.

There are also some other options under the "Optional" section. Usually it contains some other optional settings for the OAuth provider. For GitHub, you can specify other "Scope" or determine whether to use "State" to validate the callback. For difference service, there are usually different options. Please refer the service provider documentation to know more.

For a built-in supported provider, you always just need to set the top-level properties to get a minimal available setup.

Setting Callback URL

When users log in to the service with their accounts, the service will open the callback URL you set in the app. For OAuth 2.0 in a mobile app, this callback URL usually launches your app. For that works globally in the app, you need to add the callback URL to UniWebView's preference panel.

Open the preference panel (Unity → Preferences) and find "UniWebView" in the side bar. Then, expand the "Auth Callbacks Urls" and add the callback URL (authhub://auth in this example) to the list:

Handling Result

Almost done! Now, you can add a handler to get the result of the authentication flow. It is similar to Unity.UI's button action. You can prepare a method and assign it to the handlers list.

Create an empty game object (Unity Menu, GameObject -> Create Empty) to the scene and rename it as "OAuthHandler". Then add a new component by clicking the "Add Component" button in the Inspector, input "OAuthHandler" and choose "New script":

In the new OAuthHandler.cs, add the following code:

public void OnGitHubTokenReceived(UniWebViewAuthenticationGitHubToken token) {
    Debug.Log("Token received: " + token.AccessToken);
}

public void OnGitHubAuthError(long errorCode, string errorMessage) {
    Debug.Log("Error happened: " + errorCode + " " + errorMessage);
}

At last, go back to the object with UniWebViewAuthenticationFlowGitHub, click the "plus" button. Then, drag the OAuthHandler object to the field and select its related methods:

Start Authenticating

Now, you can start the authentication flow by calling StartAuthentication of the UniWebViewAuthenticationFlowGitHub component.

To do that, you first need to have a reference of the UniWebViewAuthenticationFlowGitHub. Add a new script component to the same game object where the UniWebViewAuthenticationFlowGitHub is on. Then in the new added script, add the following code in the Start() method:

void Start() {
    var githubFlow = GetComponent<UniWebViewAuthenticationFlowGitHub>();
    githubFlow.StartAuthenticationFlow();
}

 
 

TIP

Alternative, you can turn on the "Authorize On Start" option in the UniWebViewAuthenticationFlowGitHub component. It provides an easy way if you want to start the authentication flow automatically when the component starts.

The GitHub authentication should work now. By running the scene, a web view will be opened and navigate to the GitHub authorization page. You can now log in with your GitHub account to the GitHub app, and get a valid access token in OnGitHubTokenReceived callback:

When log in successfully, you can find the following console log with the retrieved access token:

Token received: ${YOUR_ACCESS_TOKEN}

Store & Read the Token

Sometimes, you may want to store the token locally. UniWebView, as a web view component and with its OAuth support, does not provide any storage for the token. You need to implement it yourself.

You can read the RawValue string of the token, and store it on the device or on your server. Remember the token is sensitive data, you should not store it in plain text. Usually, it is a good idea to encrypt it before storing it.

There are several ways to encrypt and store a string in Unity, for example, the SecurePlayerPrefsopen in new window is a good one.

When you need to use the token, you can read it from the storage and create a new UniWebViewAuthenticationStandardToken object with the raw value:

var rawValue = // Read the raw value from the storage
var token = new UniWebViewAuthenticationGitHubToken(rawValue);

// Or, if you are using a subclass of UniWebViewAuthenticationStandardToken, use its `Parse` method:
var token = UniWebViewAuthenticationTokenFactory<UniWebViewAuthenticationTwitterToken>.Parse(rawValue);

Refresh Token

If in the token, there is a non-null RefreshToken property, it usually suggests that you can use it to refresh the access token.

In any compatible flow (in this example, the UniWebViewAuthenticationFlowGitHub), there is a StartRefreshTokenFlow method. You can pass the refresh token in, and the flow will try to communicate with the service provider and refresh the token. Similar to the access token authentication flow, the refresh token result will be returned in the callback too.

But instead of setting the methods for "On Authentication Finished" and "On Authentication Errored", this time you need to set "On Refresh Token Finished" and "On Refresh Token Errored":

public void OnGitHubTokenRefreshed(UniWebViewAuthenticationGitHubToken token) {
    Debug.Log("Token refreshed: " + token.AccessToken);
}

var rawValue = // Read the raw value from the storage
var token = new UniWebViewAuthenticationGitHubToken(rawValue);
if (token.RefreshToken != null) {
    githubFlow.StartRefreshTokenFlow(token.RefreshToken);
}

Other Properties

For other OAuth 2.0 providers, you can use the same setup as above, by setting the responsive fields like "Client Id" and "Callback Url", etc. There are also some common fields between different providers.

Authorize On Start

Normally, you need to call StartAuthenticationFlow to display the web view for login form.

When this is enabled, the authentication flow will start automatically when the component starts (in the Start() method).

Private Mode

The system will remember the session for a certain service. Unless the user logs out from the service in the web view, it will just reuse the last credentials if available when the user tries to log in again. To disable this behavior and allow the user to choose another account, set the "Private Mode" option to "true".

VERSIONS

When enabled, the web view will try to open the authorization page in private (incognito) mode.

On iOS, this works on iOS 13 and later.

On Android, it is not always available but depends on the Chrome version and might require users to enable the incognito mode (and support for third-party use) in Chrome's settings. Check settings with chrome://flags/#cct-incognito and chrome://flags/#cct-incognito-available-to-third-party in Chrome to see the current status.

Common Flow

Besides the built-in supported OAuth 2.0 providers, you can also use the common flow to let your user log in to any standard OAuth 2.0 provider. To adapt to a common flow, add the UniWebViewAuthenticationFlowCustomize component instead, and set the necessary properties like "Authorization Endpoint", "Token Endpoint", "Client Id" and other more:

Usually, you can find these necessary entry points information in the service provider documentation.

To receive the authorization result, set the success handler parameter to UniWebViewAuthenticationStandardToken:

public void CustomizeOAuthDone(UniWebViewAuthenticationStandardToken token) {
    Debug.Log("Token received: " + token.AccessToken);
}

public void CustomizeOAuthFailed(long errorCode, string errorMessage) {
    Debug.Log("Error happened: " + errorCode + " " + errorMessage);
}