OpenID Connect を curl を使って理解してみる

# はじめに
OpenID Connect は理論的には知っているが、実際に動作するところをみて理解を深めてみようと思った
頭で理解できるとのと使えるのは違うので、実際に動作させてみる。

難しいプログラミングはできないので、curlコマンドを利用して動作させることにする。

まずは Yahoo!ID の v1 で試してみるので、以下を参考にYahoo!ID を取得してアプリケーション登録をしておく

https://qiita.com/bakachou/items/40237bbea207f5e99cad


# OpenIDとは
ここでは、理論については省略するので、 OpenID の仕組みは以下を参考にすれば理解しやすいと思う。
https://qiita.com/TakahikoKawasaki/items/498ca08bbfcc341691fe
https://www.slideshare.net/kura_lab/openid-connect-id

# 大まかな流れ
大まかな流れは以下のようになる

1. (RPにアクセス)
2. 認証とAuthorization codeの要求
3. ログイン
4. Authorization codeの取得
4. Token の要求／応答 (refresh_token、id_token の取得)
5. リソースアクセス (ユーザ情報取得)


# OpeID Connect の実行

## RPにアクセス
RPにアクセスすると、クライアントにもどして IdP に認証要求をリダイレクトするのだが、この RP の処理は省略する。

※）なにか簡単な RP があればそのうち追加します。

## Authorization codeの取得

ここでは、「認証とAuthorization codeの要求」、「ログイン」、「Authorization codeの取得」を一括でブラウザを利用して行う。

以下のURLをブラウザに入力してアクセスする。

```
https://auth.login.yahoo.co.jp/yconnect/v1/authorization?response_type=code+id_token&client_id=＜クライアントID
＞&redirect_uri=https://www.google.com&state=xyz&scope=openid+profile&nonce=abc
```

|項目|値|備考|
|---|---|---|
|response_type|code+id_token|たぶん codeだけでいいはずだが「code」、「id_token」を指定する。|
|client_id|クライアントID|[この画面](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F304109%2F56b3a45b-c9a9-2a50-f076-4888e7f9c3e7.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=e946d4ee202482a5825c23d01c74e8b8)にあるクライアントID(v1ではアプリケーションIDとある)|
|redirect_uri|https://www.google.com|[この画面](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F304109%2F56b3a45b-c9a9-2a50-f076-4888e7f9c3e7.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=e946d4ee202482a5825c23d01c74e8b8)にある「コールバックURL」|
|state|xyz|ランダムな数値|CSRF対策のため、なんでもよいのでランダム文字列を入力|
|scope|openid+profile|「openid」は必須の値で、ユーザー識別子の取得。「profile」を指定すると、姓名・生年・性別の取得。「email」を指定すると、「メールアドレス」と「確認済みフラグ」を取得。「address」を指定すると、「住所情報」を取得。|
|nonce|abc|リプレイアタック対策のパラメーターで、ランダムな文字列|

Yahoo!IDでのログイン画面が表示されるのでログインすると、アクセスすると以下のようなURLが表示されるので、この「code」の値が「Authorization code」となる。

```
https://www.google.com/?code=kgb38qta&state=xyz
```

## トークン (access_token、refresh_token、id_token) の取得
Tokenを取得するために、HTTPリクエストのヘッダーやデータに以下の値を入力する必要があるため curl コマンドで実行する

```
curl -H 'Authorization: Basic ＜client_id:client secret をbase64した値＞' -d \
"grant_type=authorization_code&code=＜Authorization codeの取得で返ってきたcodeの値＞&redirect_uri=https://www.google.com" \
https://auth.login.yahoo.co.jp/yconnect/v1/token
```

実行した結果、いかのような JSONが返ってくる。

```
{
    "access_token": "＜長いので省略＞",
    "token_type": "bearer",
    "expires_in": "3600",
    "refresh_token": "AJu7El8nU4DpI2xTTSa8UWqRqLJ.4f4zWy9R6EEbVtRkmsm.vsg-",
    "id_token": "＜長いので省略＞"
}
```
ちなみに、同じリクエストを何回も送信できない。以下のエラーとなる
(コンソール消したりで) トークンが分からなくなった場合は、もう一度、「Authorization codeの取得」を実施してからやり直す

```
{"error":"invalid_request","error_description":"token is invalid.","error_code":"104"}
```

Token が invalid ということでなんじゃろ？っと思っていたが、以下の通り意味が違っていた。
やっぱり「invalid_grant」だよなぁ
https://ritou.hatenablog.com/entry/20121107/1352299926

※）テスター根性なら、このテストは失敗になってるんだがｗｗｗ

# リソースアクセス (ユーザ情報取得)

得られたトークンを利用してユーザ情報を取得する。

```bash
curl -H 'Authorization: Bearer ＜access_token＞' \
> https://userinfo.yahooapis.jp/yconnect/v1/attribute?schema=openid
```
以下のようにユーザ情報が所得出来る

```
{"user_id":"45GNYH43EWZYRTZ4QN65LTMUAQ","name":"bakachou","given_name":"chou","given_name#ja-Kana-JP":"","given_name#ja-Hani-JP":"chou","family_name":"baka","family_name#ja-Kana-JP":"","family_name#ja-Hani-JP":"baka","gender":"male","locale":"ja-JP","birthday":"1111"}
```