LINE WORKS API の Token を OAuth で取得してみる

LINE WORKS API の多くは、以前に紹介した Service Account による JWT 認証で取得した Access Token を指定して利用することができますが、Drive API と Mail API は、ユーザーアカウントによる OAuth 認証で取得した Access Token でなければ利用することができません。

LINE WORKS API を利用するための OAuth の利用については、[こちら](https://developers.worksmobile.com/jp/docs/auth-oauth) を参照してください。

LINE WORKS の OAuth では、javascript によるリダイレクトが行われるため、基本的にはブラウザでアクセスする必要があり、スクリプトから簡単に Token を取得する、というわけにはいきません。
今回は、WebDriver を利用して Edge を起動し、OAuth による Access Token の取得を試してみます。


#### 準備.1 : Redirect URL の登録
JWT (Service Account) を利用の際には `Redirect URL` の登録は不要でしたが、OAuth を利用するためには、アプリに対して `Redirect URL` を登録する必要があります。
アプリの構成は済んでいる前提で、以下の手順で `Redirect URL` を登録します。 

[Develoepr Console](https://dev.worksmobile.com/jp/console/openapi/v2/app/list/view) にアクセスし、[API > アプリ] の順に進みます。
ページ下の [変更] ボタンをクリックし、`Redirect URL` にリダイレクト先の URL を入力し、[追加] > [保存] の順にクリックします。

`Redirect URL` には、通常は、利用する Web アプリで、Access Token の取得に必要となる `Authorization Code` を受け取るページを指定します。今回は、Web サーバーを立てずに OAuth を利用しますので、`https://localhost` と入力しておきます。

また、OAuth Scope には、`file` と `mail` を指定しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667330/9e2bb3b0-f701-ff8a-3e6f-d4aa65609838.png)


#### 準備.2 : WebDriver の入手
WebDriver は、ブラウザによる各種アクセスなどを自動化する仕組みです。
WebDriver はブラウザごとに提供されていますが、今回は Edge の操作を試してみます。
下の URL から、使用している環境・Edge のバージョンに該当するモジュールをダウンロードして、zip を展開の上、実行ファイルを取得してください。
https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver

取得したファイルを実行すると、WebDriver は、既定では Port 9515 で HTTP リクエストを受信するよう起動します。
この Port に対して処理内容を記述した HTTP リクエストを送信することで、ブラウザに特定 URL へのアクセスをさせたり、ページ上のコンテンツを取得したりすることができます。

HTTP リクエストを介したやり取りなので、cURL などを利用しても WebDriver を介してブラウザをコントロールすることも可能ですが、取得した Token をスクリプト内で利用することも考えて、これまでのように PowerShell から利用してみます。

Memo : 
動作確認はしていませんが、同じ方法で、Chrome も使用できると思います。
Chrome 用の WebDriver は、以下からダウンロードできます。
https://googlechromelabs.github.io/chrome-for-testing/


#### 1. WebDriver 起動
何も考えず、ダウンロードした WebDriver の実行ファイルを実行してください。
コンソール ウィンドウに、こんな感じのメッセージが表示されれば起動成功です。

```
Starting Microsoft Edge WebDriver 120.0.2210.61 (50ab4bd76cf1b5ff9d6705778b6ee170df56f154) on port 9515
To submit feedback, report a bug, or suggest new features, please visit https://github.com/MicrosoftEdge/EdgeWebDriver

Only local connections are allowed.
Please see https://aka.ms/WebDriverSecurity for suggestions on keeping Microsoft Edge WebDriver safe.

Microsoft Edge WebDriver was started successfully.
```

#### 2. Edge の起動
それでは、以下の PowerShell を実行して、WebDriver から Edge を起動してみます。

```PowerShell
$bootBoy = @{
    capabilities = {}
}
$bootResponse = Invoke-RestMethod -Uri "http://localhost:9515/session" -Method POST -body (ConvertTo-Json $bootBoy)
$sessionId = $bootResponse.value.sessionId
```

今後は、起動した Edge に紐づいた `SessionId` を用いて、Edge とやり取りをしていきます。

#### 3. Authorization Code の発行
アプリの `Client ID`、アプリで必要とする `Scope`、アプリに登録されている `Redirect URL`、CSRF 対策のための任意の文字列 `state` を元に構成した Autorize URL にアクセスします。

```PowerShell
$redirectUrl = "https://localhost"
$clientId = "wMM6Ptxxxxxxxx"
$scope = "file mail"
$state = "state"

$authReuestbody = @{
    url = "https://auth.worksmobile.com/oauth2/v2.0/authorize?client_id=$clientId&redirect_uri=$redirectUrl&scope=$scope&response_type=code&state=$state"
}
$authRes = Invoke-RestMethod -Uri "http://localhost:9515/session/$sessionId/url" -Method POST -body (ConvertTo-Json $authReuestbody) 
```

Edge ブラウザで、認証画面が表示されますので、要求されている `API Scope` を確認の上、ID とパスワードを入力して、[ログイン] をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667330/31a98bdd-eacc-2c0d-646b-90dba2ed637d.png)

ログオンすると、指定した `Redirect URL` にリダイレクトされ、その際の Query Parameter として、Authorization Code が含まれています。

WebDriver を介して、現在の URL を取得し、Query parameter から Authorization Code を取得します。
ログインしてから Step By Step で PowerShell を実行する場合には、以下のコードで Authorization Code が取得してください。

```PowerShell
#do{
#    start-sleep -Seconds 1
    $res = Invoke-RestMethod -Uri "http://localhost:9515/session/$sessionId/url" -Method GET
#}while ($false -eq $res.value.startswith($redirectUrl))

$parsedURL = $res.value.Split('?')[1]
$paramsCollection = [System.Web.HttpUtility]::ParseQueryString($parsedUrl)
$authCode = $paramsCollection["code"]
```
Edge の起動から Authorization Code の取得までをスクリプト化したい場合には、コメントアウトを外してください。
ログイン操作に時間を要することを考慮して、定期的に現在の URL を取得します。
現在の URL が `Redirect URL` に指定した値から始まっていれば、ログイン操作が終了しています。

ブラウザが必要なのはこのステップまでですので、以下を実行して、Edge を閉じてしまいましょう。

```PowerShell
Invoke-RestMethod -Uri "http://localhost:9515/session/$sessionId" -Method Delete
```
WebDrive はまだ実行されたままですので、必要に応じて別途終了してください。

#### 4. Token の取得

取得した Authorization Code を使って、Token を取得します。

```PowerShell
$clientSecret = "CrvbzPxxx"
$getTokenbody = @{
    code = $authCode
    grant_type = "authorization_code"
    client_id = $clientId
    client_secret = $clientSecret
}

$tokenRes = Invoke-RestMethod -uri "https://auth.worksmobile.com/oauth2/v2.0/token" -Method POST -body $getTokenbody 

write-host "access token is   :" $tokenRes.access_token 
write-host "refresh token is  :" $tokenRes.refresh_token 
write-host "token scope is    :" $tokenRes.scope 
write-host "token expires in  :" $tokenRes.expires_in 
```


これで、以下のように、User Account による Access Token が取得できました。
```
access token is   : jp1ASDAA0zWLm44Gfm267F3aFr0bOD2TrOt9VtS/jJXHcYl5kYKcam3OtlJf1eVusTlrsQe/imR65NN2WOyBwXIfR85LEdHScPu/oZRMFywE9Rk2NkEv21JJiMyFpkFEky2ECnj5VwVpaFtGuvN594O5+VZSvTZrNMzQHTlM8UFAZA6xlWO1qCeQ5NpF6bK8ferKH0yE1vYtE8cmPc6eIU4w+muLemKrD7RMGp3ZGbUSvoRPZlC5esQB3IAxxikLa5oS60aAAo3XbWsdB0I=.kwiu9yovfcs8Rumz2QSOg
refresh token is  : jp1ALKAhfVF82RpjYbgO/0nO4BGxImhasb1kp/bdYyhja3bzdU0pmox/ZA/E7puZm4hZcit8Fgu9FhPkUwydyRvqjN9LDacjw11fZqi1Yxtbu7ZB/r12ZD2RK0OX0iLPqjtteoCn4QDwYBLNaga6QzNCAPsYMir7fPcFySgRFBoBvo/r2qY/v5fMULzGKFw==.kwiu9yNovfcs8Rum2QSOg
token scope is    : file mail
token expires in  : 86400
```

あとは、この Token で、Drive API、Mail API を含む、LINE WORKS API をご利用いただけます。