Help us understand the problem. What is going on with this article?

Deno による OAuth 2.0 と OpenID Connect の実装(Authlete)

1. 概要

Authlete 公式リポジトリより

をリリースしました。

deno-fen-oauth-server は OAuth 2.0 および OpenID Connect をサポートする認可サーバーとして、deno-fen-resource-server はその認可サーバーを利用するリソースサーバー (Web API) として機能します。

本文書ではこれらの利用方法について解説します。

1.1. 前提

◎ 事前に Authlete 上でアカウントを取得していることが必須となります。サインアップの方法等についてはこちらのドキュメントを参照ください。

◯ 事前に OAuth 2.0 および Authlete の概要について把握しておくことを推奨します。必要に応じて、以下のドキュメントを参考にしてください。

2. 利用手順

2.1. クレデンシャルズの準備

2.1.1. サービスのクレデンシャルズ

Authlete が提供するサービスオーナーコンソールにログインし、サービス詳細ページ (https://so.authlete.com/{service-api-key}) へ移動します。

service-details.png

「基本情報」タブ内の項目にある API キーAPI シークレットの値をメモしておきます。

2.1.2. クライアントのクレデンシャルズ

Authlete が提供するデベロッパーコンソール (https://cd.authlete.com/{service-api-key}) にログインし (ログイン ID とパスワードは、2.1.1. で取得したサービスの API キーAPI シークレットになります) クライアント詳細ページへ移動します。

app-details.png

「基本情報」タブ内の項目にある クライアント IDクライアントシークレットの値をメモしておきます。

2.2. 認可サーバーのセットアップ

2.2.1. ソースコードのダウンロード

$ git clone https://github.com/authlete/deno-fen-oauth-server.git
$ cd deno-fen-oauth-server

2.2.2. 設定ファイルの編集

authlete.json を編集し、以下のように 2.1.1. で取得したサービスのクレデンシャルズの値を設定します。

authlete.json
{
  "baseUrl": "https://api.authlete.com/api",
  "serviceApiKey": "17415701171",
  "serviceApiSecret": "E0ZUYPE7gQ1qG37mTsYB-ar-WD_OMIJEnXnL5N4eOfw"
}

2.2.3. サーバー起動

下記コマンドで認可サーバーを起動します。

# ポート 1902 で起動。
$ deno run --allow-net --allow-read --config tsconfig.json src/server.ts

2.3. リソースサーバーのセットアップ

2.3.1. ソースコードのダウンロード

$ git clone https://github.com/authlete/deno-fen-resource-server.git
$ cd deno-fen-resource-server

2.3.2 設定ファイルの編集

2.2.2 と同様に、authlete.json を編集し、サービスのクレデンシャルズの値を設定します。

2.3.3. サーバー起動

下記コマンドでリソースサーバーを起動します。

# ポート 1903 で起動。
$ deno run --allow-net --allow-read --config tsconfig.json src/server.ts

2.4. 動作確認

2.4.1. 認可サーバー

ここでは OAuth 2.0 のいくつかのフローを利用して、起動した認可サーバーからアクセストークンが払い出されることを確認します。

2.4.1.1. 認可コードフロー (RFC 6749, 4.1. Authorization Code Grant)

まず、認可サーバーの認可エンドポイントにブラウザでアクセスします。認可エンドポイントの URL は以下のようになります。

# {client-id} → 2.1.2 で取得したクライアント ID の値で置換。
http://localhost:1902/api/authorization?client_id={client-id}&response_type=code

すると、下図のように認可ページが返却されます。

authorization-page_360.png

ログインフォームに以下のようにダミーユーザーの認証情報を入力し、「Authorize」ボタンを押下します。

  • Login ID → john
  • Password → john

(注) ダミーユーザーの情報については以下のファイルを参照してください。
deno-fen-oauth-server/blob/master/src/db/user_dao.ts

すると、以下のようにリダイレクトされるので、リダイレクト先の URL に付与されている認可コードの値 (code パラメーターの値) をメモしておきます。

redirected_with_code_modified.png

次に、以下のように認可サーバーのトークンエンドポイントへアクセスします。

# {client-id} → 2.1.2 で取得したクライアント ID の値で置換。
# {code} → 上でメモした認可コードの値で置換。
curl -v -X POST \
-d 'client_id={client-id}' \
-d 'grant_type=authorization_code' \
-d 'code={code}' \
http://localhost:1902/api/token

リクエストが成功すると、以下のようにアクセストークンの情報等を含むレスポンスが返却されます。

{
  "scope": null,
  "expires_in": 86400,
  "token_type": "Bearer",
  "refresh_token": "B3lBVAGTQW7EGFjEi8zSxRWpGNUnUX7L-YNuskuCXyY",
  "access_token": "4JA3nS8Z76pnwMqP9n7XvIffwCgnyvMMG4u_dAdmlKw"
}

2.4.2.1. クライアント・クレデンシャルズフロー (RFC 6749, 4.4. Client Credentials Grant)

以下のように認可サーバーのトークンエンドポイントへリクエストを送信します。

# {client-id} → 2.1.2 で取得したクライアント ID の値で置換。
# {client-secret} → 2.1.2 で取得したクライアントシークレットの値で置換。
curl -v -X POST \
-u '{client-id}:{client-secret}' \
-d 'grant_type=client_credentials' \
http://localhost:1902/api/token

リクエストが成功すると、以下のようにアクセストークンの情報等を含むレスポンスが返却されます。

{
  "access_token": "9qHLl6HimbIh21MNMulJjnqO-EXS_6gTAHAPjJyH6f0",
  "scope": null,
  "token_type": "Bearer",
  "expires_in": 86400
}

2.4.2. リソースサーバー

上記で発行したアクセストークンを用いて、リソースサーバー上の Time エンドポイントへのアクセスを試みます。

2.4.2.1. 正常系フロー

以下のように、アクセストークンを Authorization ヘッダーに付与して Time エンドポイントへリクエストを送信してください。

# {access-token} → 2.4.1 で取得したアクセストークンの値で置換。
curl -v -H 'Authorization: Bearer {access-token}' \
http://localhost:1903/api/time

リクエストが成功すると、以下のようなレスポンスが得られます。

{
  "year": 2020,
  "month": 8,
  "day": 18,
  "hour": 3,
  "minute": 21,
  "second": 12,
  "millisecond": 664
}

2.4.2.2. 異常系フロー(アクセス拒否)

次に、アクセストークンを付与せずに Time エンドポイントへのアクセスを試みます。

curl -v http://localhost:1903/api/time

すると、以下のように当該エンドポイントへのアクセスが拒否されることが確認できます。

> HTTP/1.1 400 Bad Request
> content-length: 0
> cache-control: no-store
> pragma: no-cache
> www-authenticate: Bearer error="invalid_token",error_description="[A057301] The request does not contain a valid access token.",error_uri="https://docs.authlete.com/#A057301"
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away