はじめに
Auth0 を使った iOS アプリの認証機能の実装を経験しました。
せっかくなので、復習を兼ねて Auth0 iOS SDK を使って Universal Login によるログインを実装する方法 をまとめます。
本記事では、UIKit + Swift Package Manager(SPM) で、
- ログイン
- ログアウト
- 認証情報の保存/復元
までを一通り実装します。
Auth0とは
Auth0 は、Okta 社が提供している認証・認可プラットフォームです。
Web アプリケーションだけでなく、モバイルアプリケーション(iOS / Android)にも対応しています。
Auth0 には Universal Login という仕組みがあり、これを用いることで
- ログイン UI
- 認証フロー(ID/パスワード、パスキー認証、SNSログインなど)
を Auth0 側に任せることができます。
今回作るもの
今回は以下のアプリケーションを作成します。
- ログインボタンタップ時、Universal Login を表示する Auth0のログイン処理 を実行
- ログイン処理成功時
- 認証情報を保存
- ログインユーザーのメールアドレスを画面に表示
- ログイン処理成功時
- ログアウトボタンタップ時、ブラウザのセッション情報を破棄する Auth0のログアウト処理 を実行
- ログアウト処理成功時
- 認証情報を破棄
- 「未ログイン」を表示
- ログアウト処理成功時
- アプリ起動時、保存されている認証情報を取得
- 有効な認証情報がある場合、ユーザーのメールアドレスを画面に表示
- それ以外の場合、「未ログイン」を表示
環境
- Xcode 16.4
- iOS 16.0+
- UIKit
- Swift Package Manager(SPM)
- Auth0 SDK for Apple platforms(auth0.swift)
https://github.com/auth0/Auth0.swift/
Auth0 側の事前準備
0. Auth0アカウントの作成・テナント準備
Auth0 を利用するには、アカウント登録とテナントの作成が必要です。
Auth0 には無料プランがあり、今回の内容は無料プラン内で実施できます。
1. Auth0 アプリケーション作成
-
Auth0 ダッシュボードの アプリケーション ページを開き、「+アプリケーションを作成」をタップ
-
任意のアプリケーション名を入力し、アプリケーションの種類を ネイティブ で選択し、「作成」をタップ
以下はアプリケーション名をMy Mobile Appとした場合です。

2. ログイン用ユーザーの作成
動作確認用に、ログインで使用するユーザーを作成します。
iOS プロジェクトの準備・SDKインストール
0. iOS プロジェクト作成
Xcode で新規に iOS プロジェクトを作成します。
- Interface:Storyboard
- Language:Swift
※ 既存プロジェクトに組み込む場合、この手順は不要です。
1. Auth0 iOS SDK を SPM でインストール
今回は Swift Package Manager(SPM) を使用して、 Auth0 SDK をインストールします。
-
Xcode メニューから
-
右上の検索欄に以下の URL を指定し検索し、「auth0.swift」を選択して、「Add Package」をタップ
https://github.com/auth0/Auth0.swift
これで Auth0 SDK の導入は完了です。
以下のパッケージが追加されていると思います。
- Auth0
- JWTDecode
- SimpleKeychain
2. Auth0.plist の作成
Auth0 アプリケーションと通信するために、以下の情報が必要です。
- Client ID
- Domain
これらの情報は Auth0.plist を作成し、そこに記載する必要があります。
-
Xcode メニューから
-
「Property List」を選択し、「Next」をタップ
-
Auth0.plistに以下の内容を記載する{}で囲われている部分はご自身のAuth0アプリケーションの内容に置き換えてください。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>ClientId</key> <string>{Auth0 アプリケーションの Client ID(キャプチャの赤枠)}</string> <key>Domain</key> <string>{Auth0 アプリケーションの Domain(キャプチャの青枠)}</string> </dict> </plist>例:
- Auth0 アプリケーションの Client ID :
aaa - Auth0 アプリケーションの Domain:
bbb
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>ClientId</key> <string>aaa</string> <key>Domain</key> <string>bbb</string> </dict> </plist> - Auth0 アプリケーションの Client ID :
Auth0アプリケーションに Callback URL / Logout URL の設定
Universal Login では、ログイン・ログアウト完了後に ブラウザからアプリへ戻るための URL が必要です。
- ログイン完了後 → Callback URL
- ログアウト完了後 → ログアウト URL
設定する値は以下で、どちらも同じ値になります。
{}で囲われている部分はご自身の環境の内容に置き換えてください。
{iOSアプリのBundleIdentifier}://{Auth0 アプリケーションの Domain}/ios/{iOSアプリのBundleIdentifier}/callback
例:
- iOSアプリのBundleIdentifier:
com.sample.auth0 - Auth0 アプリケーションの Domain:
bbb
com.sample.auth0://bbb/ios/com.sample.auth0/callback
Auth0 アプリケーションの設定画面を開き、
- 許可する Callback URL
- 許可するログアウト URL
に上記の URL を設定し、「保存」をタップします。
本記事では最小構成とするため、iOS の カスタムURLスキーム を用いて Callback URL / Logout URL を設定しています。
Universal Links を利用することも可能ですが、その場合はAssociated Domainsの設定や Auth0アプリケーションへの追加の設定などが必要になるため、本記事では扱っていません。
https://auth0.com/docs/ja-jp/quickstart/native/ios-swift/interactive#callback-url%E3%81%A8%E3%83%AD%E3%82%B0%E3%82%A2%E3%82%A6%E3%83%88url%E3%82%92%E6%A7%8B%E6%88%90%E3%81%99%E3%82%8B
ログイン処理の実装
前準備
Storyboard 上に以下を配置します。
- ログインボタン UIButton(ログインボタン)
- ログイン状態を表示する UILabel
ViewController に IBOutlet / IBAction を接続します。
- ログインボタンをタップした時の処理(didTapLoginButton)
- ログイン状態を表示する UILabel(textLabel)
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var textLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
textLabel.text = "未ログイン"
}
@IBAction func didTapLoginButton(_ sender: UIButton) {
}
}
ログイン処理(Auth0.webAuth().start)
ログインボタンタップ時の処理(didTapLoginButton)に、Auth0のログイン処理を記載します。
この処理を呼び出すと、Auth0の Universal Login が表示されます。
ログイン成功時、取得した ID Token からメールアドレスを取り出して画面に表示し、
ログイン失敗時、エラーの内容を表示するようにしています。
import UIKit
import Auth0
import JWTDecode
class ViewController: UIViewController {
...
@IBAction func didTapLoginButton(_ sender: UIButton) {
// Auth0 ログイン処理
Auth0
.webAuth()
.start {[weak self] result in
guard let self else { return }
switch result {
case .success(let credentials):
// ログイン成功時
guard let idToken = try? decode(jwt: credentials.idToken),
let userEmail = idToken["email"].string else { return }
print("idToken: \(idToken)")
self.textLabel.text = "ログインユーザー: \(userEmail)"
case .failure(let error):
// ログイン失敗時
self.textLabel.text = "ログイン失敗: \(error)"
}
}
}
}
認証成功時、ユーザーが認証されたことを示す ID Token を取得できます。
ID Token にはユーザー情報が内包されています。
JWT形式のためデコードすることで、ユーザー名やメールアドレスなどのユーザー情報を参照できます。
guard let idToken = try? decode(jwt: credentials.idToken),
let userEmail = idToken["email"].string else { return }
以下のサイトに ID Token を貼り付けると中身を確認できます。
Auth0ログイン処理では、.scope() や .audience() などのオプション指定が可能です。
本記事では最小構成のため指定していませんが、用途に応じて設定してください。
例えば、リフレッシュトークンを受け取る場合は、.scope("openid offline_access") のような指定が必要です。
ログアウト処理の実装
前準備
Storyboard 上に以下を配置します。
- ログアウト用 UIButton(ログアウトボタン)
ViewController に以下の処理を追加
- ログアウトボタンをタップした時の処理(didTapLogoutButton)
import UIKit
import Auth0
import JWTDecode
class ViewController: UIViewController {
...
@IBAction func didTapLogoutButton(_ sender: UIButton) {
}
}
ログアウト処理(Auth0.webAuth().clearSession)
ログアウトボタンタップ時の処理(didTapLogoutButton)に、Auth0のログアウト処理を記載します。
@IBAction func didTapLogoutButton(_ sender: UIButton) {
// Auth0 ログアウト処理
Auth0
.webAuth()
.clearSession {[weak self] result in
guard let self else { return }
switch result {
case .success:
// ログアウト成功
self.textLabel.text = "未ログイン"
case .failure(let error):
// ログアウト失敗
self.textLabel.text = "ログアウト失敗: \(error)"
}
}
}
Universal Login では、ログイン成功時ブラウザ側に認証セッションが残ります。
ログイン実行時、ブラウザに認証セッションがある場合、ログインID・パスワードを入力する認証画面がスキップされます。
これにより1つのアプリで認証を行うことで、別アプリへの認証をスキップできるSSOが可能になります。
別ユーザーでのログインを行うためには、ブラウザのセッションを明示的に破棄する Auth0のログアウト処理が必要になります。
Auth0ログイン処理にて.useEphemeralSession()を指定することで、ブラウザに認証情報を保存する機能をオフにできます。
この場合は認証情報が保存されないのでAuth0のログアウト処理を実施する必要はなく、アプリ内の認証情報を破棄するだけで良くなります。
ただしSSOの機能は使用できなくなります。
https://github.com/auth0/Auth0.swift/blob/master/FAQ.md#if-you-dont-need-sso
認証情報の保存・復元・破棄
ログイン成功時に取得した認証情報の保存は、
Auth0 SDK が提供する CredentialsManager を使って行えます。
CredentialsManager のインスタンスを保持するプロパティを作成
import UIKit
import Auth0
import JWTDecode
class ViewController: UIViewController {
@IBOutlet weak var textLabel: UILabel!
let credentialsManager: CredentialsManager = CredentialsManager(authentication: Auth0.authentication())
...
}
ログイン成功時、認証情報を保存する(.store())
ログイン成功時に、以下の認証情報を保存する処理を追加します。
@IBAction func didTapLoginButton(_ sender: UIButton) {
// Auth0 ログイン処理
Auth0
.webAuth()
.start {[weak self] result in
guard let self else { return }
switch result {
case .success(let credentials):
// ログイン成功時
guard let idToken = try? decode(jwt: credentials.idToken),
let userEmail = idToken["email"].string else { return }
print("idToken: \(idToken)")
self.textLabel.text = "ログインユーザー: \(userEmail)"
// 認証情報を保存
if self.credentialsManager.store(credentials: credentials) {
print("認証情報保存成功")
}
case .failure(let error):
// ログイン失敗時
self.textLabel.text = "ログイン失敗: \(error)"
}
}
}
ログアウト成功時、認証情報を破棄する(CredentialsManager.clear() )
ログアウト成功時に、認証情報を破棄する処理を追加します。
@IBAction func didTapLogoutButton(_ sender: UIButton) {
// Auth0 ログアウト処理
Auth0
.webAuth()
.clearSession {[weak self] result in
guard let self else { return }
switch result {
case .success:
self.textLabel.text = "未ログイン"
// 認証情報を破棄
if self.credentialsManager.clear() {
print("認証情報破棄成功")
}
case .failure(let error):
self.textLabel.text = "ログアウト失敗: \(error)"
}
}
}
アプリ起動時、保存した認証情報を取得する
アプリ起動時、有効な認証情報が存在するかをチェックし、ユーザーのメールアドレスを取得する処理を追加する。
override func viewDidLoad() {
super.viewDidLoad()
// 認証情報をチェックし、ログインユーザーのメールアドレスを取得
if credentialsManager.hasValid(),
let userEmail = credentialsManager.user?.email {
self.textLabel.text = "ログインユーザー: \(userEmail)"
return
}
textLabel.text = "未ログイン"
}
これでログイン時に受け取った認証情報を保存することができ、アプリ起動時に認証情報を利用できます。
今回はユーザー情報を取り出しましたが、以下のようにすれば認証時に受け取ったアクセストークンを取得することもできます。
let cre = CredentialsManager(authentication: Auth0.authentication())
cre.credentials { result in
switch result {
case .success(let credentials):
let accessToken = credentials.accessToken
print(accessToken)
case .failure(let error):
print(error)
}
}
まとめ
今回は Auth0 iOS SDK を用いた Universal Login の実装方法をご紹介しました。
Auth0 の Universal Login を使うことで、認証 UI や認証処理を自前で実装する必要がなく、
iOS 側では SDK を利用してログイン/ログアウト処理を呼び出すだけで良いです。
また Auth0 iOS SDK を用いることで、ログイン/ログアウトだけではなく、JWTのデコードや認証情報の保存を行うことができます。
最終コード
import UIKit
import Auth0
import JWTDecode
class ViewController: UIViewController {
@IBOutlet weak var textLabel: UILabel!
let credentialsManager: CredentialsManager = CredentialsManager(authentication: Auth0.authentication())
override func viewDidLoad() {
super.viewDidLoad()
// 認証情報をチェックし、ログインユーザーのメールアドレスを取得
if credentialsManager.hasValid(),
let userEmail = credentialsManager.user?.email {
self.textLabel.text = "ログインユーザー: \(userEmail)"
return
}
textLabel.text = "未ログイン"
}
@IBAction func didTapLoginButton(_ sender: UIButton) {
// Auth0 ログイン処理
Auth0
.webAuth()
.start {[weak self] result in
guard let self else { return }
switch result {
case .success(let credentials):
// ログイン成功時
guard let idToken = try? decode(jwt: credentials.idToken),
let userEmail = idToken["email"].string else { return }
print("idToken: \(idToken)")
self.textLabel.text = "ログインユーザー: \(userEmail)"
// 認証情報を保存
if self.credentialsManager.store(credentials: credentials) {
print("認証情報保存成功")
}
case .failure(let error):
// ログイン失敗時
self.textLabel.text = "ログイン失敗: \(error)"
}
}
}
@IBAction func didTapLogoutButton(_ sender: UIButton) {
// Auth0 ログアウト処理
Auth0
.webAuth()
.clearSession {[weak self] result in
guard let self else { return }
switch result {
case .success:
self.textLabel.text = "未ログイン"
// 認証情報を破棄
if self.credentialsManager.clear() {
print("認証情報破棄成功")
}
case .failure(let error):
self.textLabel.text = "ログアウト失敗: \(error)"
}
}
}
}
参考
https://auth0.com/docs/ja-jp/libraries/auth0-swift
https://github.com/auth0/Auth0.swift/tree/master
https://dev.classmethod.jp/articles/auth0-access-token-id-token-difference/
https://auth0.com/blog/id-token-access-token-what-is-the-difference/












