【Android】Auth0 公式のクイックスタートを参考に Kotlin でユニバーサルログインを組み込んでみた
はじめに
テントの中から失礼します、IoT 事業部のてんとタカハシです!
Android アプリ開発も Auth0 も Kotlin も初心者なのですが、これらを使ってユニバーサルログインをアプリに組み込む機会がありましたので、手順を残しておこうと思います。
基本的には Auth0 公式のクイックスタートを参考にすれば何となく実装できそうなのですが、初心者の私はそこそこ躓きました。同じような初心者の方にとって参考になれば嬉しいです。
環境
- macOS Catalina v10.15.7
- Android Studio 4.2.1
参考
主に Auth0 公式のクイックスタートを参考にしました。
Android プロジェクトを作成する
Empty Activity
を選択します。
プロジェクト名はsample-auth0-login
としています。Auth0 を使用する場合は、Android の API レベルを 21 以上に設定する必要があることに注意してください。
Android API version 21 or newer is required.
Auth0 Docs > Auth0 Libraries > Auth0.Android
Auth0 アプリケーションを作成する
アプリケーション名はsample-auth0-login
としています。アプリケーションタイプはNative
を選択します。
作成したアプリケーションの Settings タブを開くと、ドメイン名とクライアント ID が表示されます。この2つは後ほどログイン画面実装時に使用します。
下にスクロールして、Allowed Callback URLs と Allowed Logout URLs を設定します。
どちらもdemo://<Auth0 ドメイン名>/android/<Android プロジェクトのパッケージ名>/callback
で入力してください。本記事の例では、Android プロジェクトのパッケージ名がcom.example.sample_auth0_login
になります。
その後は、ページ下部にある Save Changes ボタンをクリックして設定を保存してください。
Auth0 SDK を使用するための準備を行う
Auth0 Android SDK を追加する
app 内の build.gradle に下記を追記します。その後、Gradle ファイルを同期してください。
... dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'androidx.core:core-ktx:1.6.0' implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' // ★ implementation 'com.auth0.android:auth0:2.+' }
ビルド変数を設定する
Auth0 Android SDK の内部で使用されるビルド変数を設定します。
... android { compileSdkVersion 30 buildToolsVersion "30.0.3" defaultConfig { applicationId "com.example.sample_auth0_login" minSdkVersion 21 targetSdkVersion 30 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" // ★ manifestPlaceholders = [auth0Domain: "@string/com_auth0_domain", auth0Scheme: "@string/com_auth0_scheme"] } ...
実際の値は strings.xml に記載します。Auth0 のクライアント ID、ドメイン名はそれぞれの環境に合わせて変更してください。本記事ではスキーマをdemo
にします。
<resources> <string name="app_name">Auth0LoginSample</string> <!-- ★ --> <string name="com_auth0_client_id"><Auth0 のクライアント ID></string> <string name="com_auth0_domain"><Auth0 のドメイン名></string> <string name="com_auth0_scheme">demo</string> </resources>
インターネットに接続するための権限を設定する
マニフェストファイルに権限を追記します。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.sample_auth0_login"> <!-- ★ --> <uses-permission android:name="android.permission.INTERNET" /> <application ...
ログイン/ログアウト処理を持つモジュールを実装する
後述するログイン用の画面、ログアウト用の画面から Auth0 の処理を呼び出せるようにモジュールを実装しておきます。
Auth0(context)
としている箇所で、strings.xml に記載したcom_auth0_client_id
とcom_auth0_domain
の値が自動的に読み込まれます。
package com.example.sample_auth0_login import android.content.Context import com.auth0.android.Auth0 import com.auth0.android.provider.WebAuthProvider internal object AuthModule { fun loginAuthBuilder(context: Context): WebAuthProvider.Builder { return WebAuthProvider.login(Auth0(context)) .withScheme(context.getString(R.string.com_auth0_scheme)) .withScope("openid profile email") } fun logoutAuthBuilder(context: Context): WebAuthProvider.LogoutBuilder { return WebAuthProvider.logout(Auth0(context)) .withScheme(context.getString(R.string.com_auth0_scheme)) } }
ログイン画面を実装する
MainActivity にログイン用のボタンを配置します。ログインボタンがクリックされると、ユニバーサルログイン画面が起動して、ログインが成功すれば、ContentActivity に画面遷移するようにしています。
package com.example.sample_auth0_login import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Button import com.auth0.android.authentication.AuthenticationException import com.auth0.android.callback.Callback import com.auth0.android.result.Credentials class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // ログインボタンをクリックするとユニバーサルログイン画面が起動する val loginButton = findViewById<Button>(R.id.loginButton) loginButton.setOnClickListener { loginWithBrowser() } } private fun loginWithBrowser() { AuthModule.loginAuthBuilder(this) .start(this, object : Callback<Credentials, AuthenticationException> { override fun onSuccess(credentials: Credentials) { // ログインに成功したら ContentActivity に遷移する val intent = Intent(applicationContext, ContentActivity::class.java) startActivity(intent) } override fun onFailure(exception: AuthenticationException) {} }) } }
ログアウト画面を実装する
ContentActivity にログアウト用のボタンを配置します。ログアウトボタンがクリックされると、ログアウト処理が走り、MainActivity に画面遷移するようにしています。
package com.example.sample_auth0_login import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Button import com.auth0.android.authentication.AuthenticationException import com.auth0.android.callback.Callback class ContentActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_content) // ログインボタンをクリックするとログアウト処理が走る val logoutButton = findViewById<Button>(R.id.logoutButton) logoutButton.setOnClickListener { logout() } } private fun logout() { AuthModule.logoutAuthBuilder(this) .start(this, object: Callback<Void?, AuthenticationException> { override fun onSuccess(payload: Void?) { // ログアウトに成功したら MainActivity に遷移する val intent = Intent(applicationContext, MainActivity::class.java) startActivity(intent) } override fun onFailure(error: AuthenticationException) {} }) } }
デモ
ログインボタンをクリックすると、
ユニバーサルログイン画面が起動します。
ログインが成功すると、ログアウトボタンが設置されている画面に遷移します。
ログアウトボタンをクリックすると、ログイン画面に戻ります。
おわりに
Android アプリに Auth0 のユニバーサルログインを組み込むことができました。公式のクイックスタートには、プロフィールの変更などの対応についても記載がありますので、そちらの理解も深めていきたいなと思います。
今回は以上になります。最後まで読んで頂きありがとうございました!