15
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

OPENLOGIAdvent Calendar 2022

Day 9

Auth0を使ってSSOの流れを確認してみた

Last updated at Posted at 2022-12-08

はじめに

この記事はOPENLOGI Advent Calendar 2022の9日目の記事です。

業務と全く関係ないのですが、今回は個人的に気になっていたSSOの具体的な流れについて手元で環境を作り処理を追っていきたいと思います。
Auth0SSO、またその他利用しているツール類の説明は、詳しく解説されてる記事がありますので割愛させていただきます。

概要

SSOの分かりやすいフロー図がAuth0 blogにありますので、Auth0を使ったSSOの1〜13までの流れを確認します。
typical-sso.png

実際に利用する際は意識する必要はない項目もありそうですが、今回はざっと見ていければと思います。

確認準備

1. ローカル環境作成

SSOの確認なのでまずは2環境作っていきます。

作成は以下のコマンドをport番号違いで2回叩くだけです。

$ php -S localhost:8888
PHP 8.1.11 Development Server (http://localhost:8888) started

2. 外部からローカル環境へアクセスできるようにする

ngrokを利用します。
service1と2は先ほど立ち上げたローカル環境をポート番号違いで紐づけてます。

$ ngrok start service1 service2
ngrok                                                                                        (Ctrl+C to quit)

Try our new native Go library: https://github.com/ngrok/ngrok-go

Session Status                online
Account                       terumichi1209@gmail.com (Plan: Free)
Version                       3.1.0
Region                        United States (us)
Latency                       -
Web Interface                 http://127.0.0.1:4040
Forwarding                    https://6fef-60-61-127-42.ngrok.io -> http://localhost:8888
Forwarding                    https://c78d-60-61-127-42.ngrok.io -> http://localhost:8889

これで外部からアクセスできる2つのローカル環境が作成できました。

3. Auth0へ生成したドメインを反映する

Auth0管理画面にて、ご自身の環境でアプリを以下のように2つ作成します。
スクリーンショット 2022-12-03 17.08.53.png

各アプリには生成したURLを設定します。
スクリーンショット 2022-12-03 17.13.51.png

データベースを利用せず、ソーシャルログインだけの場合はこれでAuth0側は準備完了です。
スクリーンショット 2022-12-03 17.18.25.png

4. Auth0のアプリ情報を設定する

サービスごとにディレクトリを切っただけのアプリを用意します。
スクリーンショット 2022-12-03 17.28.41.png

index.phpAuth0クイックスタートのサンプルコードの寄せ集めになります。
ドメインやパス、Auth0のアプリ情報を変えて、2つの index.php に設定します。

<?php
use Steampixel\Route;

const ROUTE_URL_INDEX = 'https://f272-60-61-127-42.ngrok.io/service1';
const ROUTE_URL_LOGIN = ROUTE_URL_INDEX . '/login';
const ROUTE_URL_CALLBACK = ROUTE_URL_INDEX . '/callback';
const ROUTE_URL_LOGOUT = ROUTE_URL_INDEX . '/logout';

require '../vendor/autoload.php';

$auth0 = new \Auth0\SDK\Auth0([
    'domain' => 'Auth0で作成したアプリのdomain',
    'clientId' => 'Auth0で作成したアプリのclientId',
    'clientSecret' => 'Auth0で作成したアプリのclientSecret',
    'cookieSecret' => 'test',
]);

Route::add('/service1', function() use ($auth0) {
    $session = $auth0->getCredentials();
    if ($session === null) {
        echo '<p>Please <a href="' . ROUTE_URL_LOGIN . '">log in</a>.</p>';
        return;
    }

    echo '<pre>';
    print_r($session->user);
    echo '</pre>';

    echo '<p>You can now <a href="' . ROUTE_URL_LOGOUT . '">log out</a>.</p>';
});

Route::add('/service1/login', function() use ($auth0) {
    $auth0->clear();
    header("Location: " . $auth0->login(ROUTE_URL_CALLBACK));
});

Route::add('/service1/callback', function() use ($auth0) {
    $auth0->exchange(ROUTE_URL_CALLBACK);
    header("Location: " . ROUTE_URL_INDEX);
});

Route::add('/service1/logout', function() use ($auth0) {
    header("Location: " . $auth0->logout(ROUTE_URL_INDEX));
});

Route::run('/');

以上で設定は完了ですので実際に見ていきましょう。

結果

それでは、1から順を追って確認します。
typical-sso.png

1. Browses to

サービス1にアクセスします。

スクリーンショット 2022-12-03 14.47.40.png

2. Redirects to

ログインボタンを押すとユニバーサルログイン画面(Auth Server)にリダイレクトします。
スクリーンショット 2022-12-03 14.51.28.png

3. Enter user logs in, or cookie is avaliable

ここではまだログインした記録となるCookie情報はないため、ユーザ情報をユニバーサルログイン画面上で入力(またはソーシャルログインなど)します。

4. Store Cookie

入力したユーザ情報がAuth0が保持するユーザと一致(もしくは新規作成に成功)した場合、Auth0側の認証はOKなのでその旨をCookieに保持します。
スクリーンショット 2022-12-03 15.22.01.png

5. Sends token and redirects

この後の認証に必要な code(token)stateが付与されてAuth0アプリで設定したcallback先にリダイレクトします。
スクリーンショット 2022-12-03 15.07.30.png

6. Uses Token to Authenticate

codeを利用して認証します。
ライブラリ内で良しなにやってくれてますね。
https://github.com/auth0/auth0-PHP/blob/main/src/Auth0.php#L300

付与されてるパラメータを利用してaccess_tokenやid_token(jwt)を生成します。
認証後に取得できるトークンは復号することで、どういったデータ持ってるかの参考になります。
スクリーンショット 2022-12-03 15.28.49.png

7. Stores domain1 Cookie

認証を終えるとCookie情報が追加されます。
スクリーンショット 2022-12-03 15.44.06.png

アプリ側では以上で無事ログインできたので、ユーザ情報が出力できました。
スクリーンショット 2022-12-03 16.04.13.png

先ほど確認したトークン内容がそのまま出てることが分かります。

8. Browsers to

次にドメインを変えてサービス2にアクセスします。

スクリーンショット 2022-12-03 16.08.48.png

9. Redirects to

ログインボタンを押して、Auth Serverにリダイレクトします。

10. Enter user logs in, or cookie is avaliable

今度はサービス1のフローで登録したCookieを保持しているため、どのユーザかAuth0上では特定できてます。
そのため、入力を省略して次のステップへ進みます。

11. Sends token and redirects

同じようにcode(token)stateが付与されてサービス2へリダイレクトします。
スクリーンショット 2022-12-03 16.22.37.png

12. Uses Token to Authenticate

省略

13. Stores domain1 Cookie

サービス1と同じようにサービス2のドメインでCookieが作成されていることが分かります。
スクリーンショット 2022-12-03 16.26.47.png

結果も同様に出てることが確認できました。
スクリーンショット 2022-12-03 16.28.24.png

最後に

いかがでしたでしょうか?

図で見るだけより実際に動かした方が理解できて(特にトークン生成周り)、記事を書いて良かったと思います。
ライブラリ内深掘りするともう少しありますが、冒頭の図の流れは追えたので今回はこの辺りで終わります。

今回の実験用に作成したコードはGithubへ上げてますので、興味がある方は手元の環境でもお試しいただけます。
https://github.com/terumichi1209/auth0_sso_sample/

15
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?