SharePoint API の accessToken どうやって取る？【後編】

# はじめに

SharePoint の API 使うときに必要な accessToken をどのように取得するか、その方法を記した記事です。

- クライアントの登録はどうやって行える？
- 認可エンドポイントやトークンエンドポイントの情報は？

なかなか、手こずりましたのでメモを残しておきます。
参考になれば幸いです。

:::note info
本記事は【後編】です。
認可コードフローでtokenを取得する部分の一連の方法を記しています。
必要な client_id と client_secret を取得する方法は【前編】を参照ください。
:::

#### 【前編】 の記事はこちら
https://qiita.com/samiii/items/cc47bb73a5e47645ce48

#### Microsoft の参考ドキュメントはこちら
https://docs.microsoft.com/ja-jp/sharepoint/dev/sp-add-ins/authorization-code-oauth-flow-for-sharepoint-add-ins

:::note info
実際は redirect_uri で code を取得して access_token 取得する ところや refresh_token 使って更新するところなどはアプリなりで実装すると思いますが、本記事では試打の方法を記していますので、curl やまだ存在しないページへリダイレクトして code 取得してたりします。適宜読み変えてご利用ください。
:::

# 4. 認可コードを取得する
「3. クライアントの登録」 で登録した クライアントの情報を使って認可コードを取得します。

# 4.1. 認可リクエストを送付

認可エンドポイントは `<site collection url>/_layouts/15/OAuthAuthorize.aspx` です。（対象サイトのサイトURLが https://samiii.sharepoint.com/teams/blue だとすると、https://samiii.sharepoint.com/teams/blue/_layouts/15/OAuthAuthorize.aspx）

そこに、下記のパラメータを付し、GETリクエストを送付します。

| パラメータ名          | 値の例                         | 説明 |
|:-------------------|:----------------------------------------|:----------------------------------------|
| response_type | code | 認可コードを要求する値です。OAuth2.0の仕様で定義されている値。 |
| client_id | epat9p9hdh4m8-ems9j-9ch7-z4tvs49w734 | 「[3.1. クライアントの登録](https://qiita.com/samiii/items/cc47bb73a5e47645ce48#31-%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%81%AE%E7%99%BB%E9%8C%B2%E3%82%A2%E3%83%89%E3%82%A4%E3%83%B3%E3%81%AE%E7%99%BB%E9%8C%B2)」で登録したクライアント ID |
| redirect_uri | https://samiii.co.jp/oauth2/redirect_uri | 「[3.1. クライアントの登録](https://qiita.com/samiii/items/cc47bb73a5e47645ce48#31-%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%81%AE%E7%99%BB%E9%8C%B2%E3%82%A2%E3%83%89%E3%82%A4%E3%83%B3%E3%81%AE%E7%99%BB%E9%8C%B2)」で登録したリダイレクト先 URL |


具体的にはどうするか？

| 上記例の場合、ブラウザで下記にアクセスでOKです！ |
|:-------------------|
| https://samiii.sharepoint.com/teams/blue/_layouts/15/OAuthAuthorize.aspx?response_type=code&client_id=epat9p9hdh4m8-ems9j-9ch7-z4tvs49w734&redirect_uri=https%3A%2F%2Fsamiii.co.jp%2Foauth2%2Fredirect_uri          |

# 4.2. 同意画面で同意する

「4.1. 認可リクエストを送付」 の通り、リクエストを送付すると、同意画面が表示されます。
問題ないことを確認して [信頼する] を押下してください。
![同意画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246440/c52faee7-f40a-8788-cb39-cb14118f5039.png)

# 4.3. 認可コードを取得する
「4.2. 同意画面で同意する」　を行った後、正常に認可コードが発行されれば、指定した redirect_url に認可コードをパラメータに含んでリダイレクトされます。

redirect_url に指定した URLは存在しなくても大丈夫です。下記のような感じでエラー表示されるかもしれませんが、アドレスバーに表示されているURLから`code`パラメータの値を取得します。取得した値が、認可コードです！

![認可コード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246440/d3c7cdb8-2a21-a023-f27e-8c9bead3ac40.png)

```HTTP:redirect_urlに返却された認可コードの例
https://samiii.co.jp/oauth2/redirect_uri?
code=9UJhwebJnKwCFJh4cEPuyXFb55Wz3waMTaj7fq2dXxaShereRg2ut6Y
Xw4MvXBWp9vNSasRe9EPVacF5Rvgqj25bXdnzeturkCYfcMKDAvwD6n6Mhh
```
※表示のため改行してますが実際は一行です
※認可コードはcodeパラメータで指定された文字列 `9UJhwebJnKwCFJh4cEPuyXFb55Wz3waMTaj7fq2dXxaShereRg2ut6YXw4MvXBWp9vNSasRe9EPVacF5Rvgqj25bXdnzeturkCYfcMKDAvwD6n6Mhh`


# 5. Azure AD の テナントの識別子を確認する
Microsoftのドキュメントを見ると、ところどころで {tenant} と書かれています。これは、操作を行いたいSharePointサイトが存在する Azure AD のテナントの識別子です。

テナントの識別子は、テナントドメイン と、ランダム文字列から成る テナントID が存在します。

テナントドメインは `samiii.onmicrosoft.com` とか `samiii.co.jp` みたいなものです。

テナントIDは `XXXXX-XXXXXXXXXXXXXXX-XXXXXXXX-XXXXX` みたいなものです。
[Azure AD テナントプロパティのページ](https://portal.azure.com/#blade/Microsoft_AAD_IAM/TenantPropertiesBlade) で確認することができます。

アクセストークンを取得するにあたって必要になりますので、自身のテナントの情報を確認してください。いずれの情報でも（テナントドメインでもテナントIDでも）OKです。


# 6. 認可コード grant で accessToken を取得する

# 6.1. トークンリクエストを送付

トークンエンドポイントは `https://accounts.accesscontrol.windows.net/{tenant}/tokens/OAuth/2` です。（テナント識別子が `XXXXX-XXXXXXXXXXXXXXX-XXXXXXXX-XXXXX` だとすると、https://accounts.accesscontrol.windows.net/XXXXX-XXXXXXXXXXXXXXX-XXXXXXXX-XXXXX/tokens/OAuth/2）

そこに、下記のパラメータを付し、POSTクエストを送付します。

| パラメータ名          | 値の例                         | 説明 |
|:-------------------|:----------------------------------------|:----------------------------------------|
| grant_type | authorization_code | 認可コード grant であることを示す値です。OAuth2.0の仕様で定義されている値。 |
| client_id | epat9p9hdh4m8-ems9j-9ch7-z4tvs49w734@XXXXX-XXXXXXXXXXXXXXX-XXXXXXXX-XXXXX | 「[3.1. クライアントの登録](https://qiita.com/samiii/items/cc47bb73a5e47645ce48#31-%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%81%AE%E7%99%BB%E9%8C%B2%E3%82%A2%E3%83%89%E3%82%A4%E3%83%B3%E3%81%AE%E7%99%BB%E9%8C%B2)」で登録したクライアント ID + "@" + テナントの識別子 |
| client_secret | AhGgcsyHGf44T8QJbTKrvsvjkVhVbQppec8Z5BhzRdBs | 「[3.1. クライアントの登録](https://qiita.com/samiii/items/cc47bb73a5e47645ce48#31-%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%81%AE%E7%99%BB%E9%8C%B2%E3%82%A2%E3%83%89%E3%82%A4%E3%83%B3%E3%81%AE%E7%99%BB%E9%8C%B2)」で登録したクライアント シークレット |
| redirect_uri | https://samiii.co.jp/oauth2/redirect_uri | 「[3.1. クライアントの登録](https://qiita.com/samiii/items/cc47bb73a5e47645ce48#31-%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%81%AE%E7%99%BB%E9%8C%B2%E3%82%A2%E3%83%89%E3%82%A4%E3%83%B3%E3%81%AE%E7%99%BB%E9%8C%B2)」で登録したリダイレクト先 URL |
| resource | 00000003-0000-0ff1-ce00-000000000000/saniii.sharepoint.com@XXXXX-XXXXXXXXXXXXXXX-XXXXXXXX-XXXXX | "00000003-0000-0ff1-ce00-000000000000/saniii.sharepoint.com@" + テナントの識別子 |
| code | 9UJhwebJnKwCFJh4cEPuyXFb55Wz3waMTaj7fq2dXxaShereRg2ut6YXw4MvXBWp9vNSasRe9EPVacF5Rvgqj25bXdnzeturkCYfcMKDAvwD6n6Mhh | 「[4. 認可コードを取得する](https://qiita.com/samiii/items/56603487ba75e65553aa#4-%E8%AA%8D%E5%8F%AF%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B)」で取得した認可コード |

具体的にはどうするか？
何かのツール等を使って、上記の通りの POST リクエストの送付を行うか
curlコマンドで下記のように実行すれば OK です。

```shell:
curl -X POST https://accounts.accesscontrol.windows.net/XXXXX-XXXXXXXXXXXXXXX-XXXXXXXX-XXXXX/tokens/OAuth/2 \
--data grant_type=authorization_code \
--data client_id=epat9p9hdh4m8-ems9j-9ch7-z4tvs49w734@XXXXX-XXXXXXXXXXXXXXX-XXXXXXXX-XXXXX \
--data client_secret=AhGgcsyHGf44T8QJbTKrvsvjkVhVbQppec8Z5BhzRdBs \
--data redirect_uri=https%3A%2F%2Fsamiii.co.jp%2Foauth2%2Fredirect_uri \
--data resource=00000003-0000-0ff1-ce00-000000000000/saniii.sharepoint.com@XXXXX-XXXXXXXXXXXXXXX-XXXXXXXX-XXXXX \
--data code=9UJhwebJnKwCFJh4cEPuyXFb55Wz3waMTaj7fq2dXxaShereRg2ut6YXw4MvXBWp9vNSasRe9EPVacF5Rvgqj25bXdnzeturkCYfcMKDAvwD6n6Mhh
```

# 6.2. トークンレスポンスの確認
「6.1. トークンリクエストを送付」を行なった結果、下記のようなjsonが返却されます。
これでアクセストークンの取得は完了です！

```json:
{
  "token_type":"Bearer",
  "expires_in":"28799",
  "not_before":"1632210195",
  "expires_on":"1632239295",
  "resource":"00000003-0000-0ff1-ce00-000000000000/saniii.sharepoint.com@XXXXX-XXXXXXXXXXXXXXX-XXXXXXXX-XXXXX",
  "access_token":"{アクセストークン文字列}",
  "refresh_token":"cgrh6cxPVMNWMDYmCuzyX95tPhfHvTFs3zmu2nqtqMZrVdfVTNktVM5UY8m4bAVw4ZXnY8m5KPYsnPCRmgCv2ZCBwJWhQYujN9hegM9c3gBUCGPjCypJ8qUFpvtSevWWVZqK6acnNdR7AfeTTQxmSpb2UaRtS6ngmD2jF3s9MnDbK8KhQKZpBUs62wA4frHpVPpd68ymD3sXHj22BJdSUZkBCKFwJCEPDY52gP4f38J7E4txGsEqCfBrhvXk555QaHSnDgYyCg6MMbxspgbcEQu6s7sXCT4dStv2Yr2Bu3SMqEBPpMydx8HEee"
}
```

# 7. リフレッシュトークン grant で accessToken を取得する
「6. 認可コード grant で accessToken を取得する」 でアクセストークン自体は取得できるのですが、有効期間が 28799秒、ということは 8時間で使えなくなります。
有効期限が切れた際に、再度１から（認可コードの取得から)やり直しても良いですが、リフレッシュトークンが有効である限りはリフレッシュトークンを用いた再発行が可能ですので、その方法も記しておきます。

# 7.1. トークンリクエストを送付

トークンエンドポイントに、下記のパラメータを付し、POSTクエストを送付します。



| パラメータ名          | 値の例                         | 説明 |
|:-------------------|:----------------------------------------|:----------------------------------------|
| grant_type | refresh_token | リフレッシュトークン grant であることを示す値です。OAuth2.0の仕様で定義されている値。 |
| client_id | epat9p9hdh4m8-ems9j-9ch7-z4tvs49w734@XXXXX-XXXXXXXXXXXXXXX-XXXXXXXX-XXXXX | 「[3.1. クライアントの登録](https://qiita.com/samiii/items/cc47bb73a5e47645ce48#31-%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%81%AE%E7%99%BB%E9%8C%B2%E3%82%A2%E3%83%89%E3%82%A4%E3%83%B3%E3%81%AE%E7%99%BB%E9%8C%B2)」で登録したクライアント ID + "@" + テナントの識別子 |
| client_secret | AhGgcsyHGf44T8QJbTKrvsvjkVhVbQppec8Z5BhzRdBs | 「[3.1. クライアントの登録](https://qiita.com/samiii/items/cc47bb73a5e47645ce48#31-%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%81%AE%E7%99%BB%E9%8C%B2%E3%82%A2%E3%83%89%E3%82%A4%E3%83%B3%E3%81%AE%E7%99%BB%E9%8C%B2)」で登録したクライアント シークレット |
| resource | 00000003-0000-0ff1-ce00-000000000000/saniii.sharepoint.com@XXXXX-XXXXXXXXXXXXXXX-XXXXXXXX-XXXXX | "00000003-0000-0ff1-ce00-000000000000/saniii.sharepoint.com@" + テナントの識別子 |
| refresh_token | cgrh6cxPVMNWMDYmCuzyX95tPhfHvTFs3zmu2nqtqMZrVdfVTNktVM5UY8m4bAVw4ZXnY8m5KPYsnPCRmgCv2ZCBwJWhQYujN9hegM9c3gBUCGPjCypJ8qUFpvtSevWWVZqK6acnNdR7AfeTTQxmSpb2UaRtS6ngmD2jF3s9MnDbK8KhQKZpBUs62wA4frHpVPpd68ymD3sXHj22BJdSUZkBCKFwJCEPDY52gP4f38J7E4txGsEqCfBrhvXk555QaHSnDgYyCg6MMbxspgbcEQu6s7sXCT4dStv2Yr2Bu3SMqEBPpMydx8HEee |「6. 認可コード grant で accessToken を取得する」で取得したリフレッシュトークン |

具体的にはどうするか？
何かのツール等を使って、上記の通りの POST リクエストの送付を行うか
curlコマンドで下記のように実行すれば OK です。

```shell:
curl -X POST https://accounts.accesscontrol.windows.net/XXXXX-XXXXXXXXXXXXXXX-XXXXXXXX-XXXXX/tokens/OAuth/2 \
--data grant_type=refresh_token \
--data client_id=epat9p9hdh4m8-ems9j-9ch7-z4tvs49w734@XXXXX-XXXXXXXXXXXXXXX-XXXXXXXX-XXXXX \
--data client_secret=AhGgcsyHGf44T8QJbTKrvsvjkVhVbQppec8Z5BhzRdBs \
--data resource=00000003-0000-0ff1-ce00-000000000000/saniii.sharepoint.com@XXXXX-XXXXXXXXXXXXXXX-XXXXXXXX-XXXXX \
--data refresh_token=cgrh6cxPVMNWMDYmCuzyX95tPhfHvTFs3zmu2nqtqMZrVdfVTNktVM5UY8m4bAVw4ZXnY8m5KPYsnPCRmgCv2ZCBwJWhQYujN9hegM9c3gBUCGPjCypJ8qUFpvtSevWWVZqK6acnNdR7AfeTTQxmSpb2UaRtS6ngmD2jF3s9MnDbK8KhQKZpBUs62wA4frHpVPpd68ymD3sXHj22BJdSUZkBCKFwJCEPDY52gP4f38J7E4txGsEqCfBrhvXk555QaHSnDgYyCg6MMbxspgbcEQu6s7sXCT4dStv2Yr2Bu3SMqEBPpMydx8HEee
```

# 7.2. トークンレスポンスの確認
「7.1. トークンリクエストを送付」を行なった結果、下記のようなjsonが返却されます。

```json:
{
  "token_type":"Bearer",
  "expires_in":"28799",
  "not_before":"1632229687",
  "expires_on":"1632258787",
  "resource":"00000003-0000-0ff1-ce00-000000000000/saniii.sharepoint.com@XXXXX-XXXXXXXXXXXXXXX-XXXXXXXX-XXXXX",
  "access_token":"{アクセストークン文字列}"
}
```

ちなみに、リフレッシュトークン grant では リフレッシュトークンは発行/返却されません。再びリフレッシュトークン grant での再発行を行いたい場合は、リフレッシュトークン自体の同じ リフレッシュトークンの使い回しで可能です。

-----

以上、[Microsotのドキュメント](https://docs.microsoft.com/ja-jp/sharepoint/dev/sp-add-ins/get-to-know-the-sharepoint-rest-service?tabs=http) に書かれている `accessToken` を取得する方法でした。

```http:Microsoftのドキュメントで記されているAPI利用例
GET https://{site_url}/_api/lists/getbytitle('{list_name}')/items
Authorization: "Bearer " + accessToken
Accept: "application/json;odata=verbose"
```

快適な SharePoint API ライフを！！！！！

:::note warn
クライアントシークレットやアクセストークンなど、ホンモノっぽいランダム文字列を本文中に記載していますが、記事を書く上で便宜上利用したランダム文字列であり、正しく登録等が行われたものではありません。実際はこの値を使っても動きませんので、ご了承ください。
:::