search
LoginSignup
6

posted at

【GAS × LINE WORKS】JWT認証

LINE WORKS APIの認証方法のひとつとしてJWT認証があります。
Service Account認証 (JWT)

LINE WORKS APIを使用するにあたりJWT認証が必要になるのですが、この処理が非常に面倒だったのでライブラリを作りました。良ければこちらを登録して使ってください。
自分でコード書きたい!って人は後ほど解説しますのでそちらを参照してください。

  1. 登録したいGoogleAppScriptを開く
  2. 「ライブラリ」の+ボタンをクリック
  3. 「ライブラリを追加」の欄に 1aLcCr3CWqfenPMyM0_FWIDUgRcTxsit9bO6BTx61NCXrCtkY2zbHBlod を入力して検索ボタンをクリック
  4. 「LINEWORKS」ライブラリが表示されるので最新バージョンを選んで追加ボタンをクリック

LINEWORKSライブラリ解説

解説ってほど中身用意してないんですが(^_-)-☆
取り合えず、今回の認証の部分だけ。

スクリプト内にLINEWORKS.getAccessToken(ENV, scopes)と記載することでTokenを取得できます。指定するパラメータは以下の通りです。

  • ENV: LINE WORKSの認証情報(下記example.gs参照)
  • scopes: 使用するAPIを指定します。Botを使いたいならbot(詳細は公式Document参照)
example.gs
function example() {
    const token = LINEWORKS.getAccessToken(getEnv_(), "bot")
    Logger.log(token)
}
function getEnv_() {
  return {
    CLIENT_ID: "xxxxxxxxxxxxxxxx",
    CLIENT_SECRET: "xxxxxxxxxxxxxxxx",
    SERVICE_ACCOUNT: "xxxxxx.serviceaccount@xxxxxxxxxx",
    PRIVATE_KEY: "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0xxxxxxxxxxxxxxxxxxxxxxxxxxxxx==\n-----END PRIVATE KEY-----"
  }
}

Reterun Value

実行ログ
{
    refresh_token=jp1AAAAhPnqSpMJrEymayxxxxxxxxxxxxxxxxxxxxxxxxDfA==,
    token_type=Bearer,
    access_token=jp1AAABFJyracgGzaC4OcpgxxxxxxxxxxxxxxxxxxxxxTMmxQ==,
    expires_in=86400,
    scope=bot
}

JSON.parseしてあるのでスクリプト上ではtoken.access_tokenと指定すればtokenを利用できます。

Code

GoogleAppsScriptでのJWT認証はこんな風に実装しています。

serviseAccount.gs
// 1. JWTを生成
function getJwt(ENV){
  const header = Utilities.base64Encode(JSON.stringify({"alg":"RS256","typ":"JWT"}), Utilities.Charset.UTF_8)
  const claimSet = JSON.stringify({
    "iss": ENV.CLIENT_ID,
    "sub": ENV.SERVICE_ACCOUNT,
    "iat": Math.floor(Date.now() / 1000),
    "exp": Math.floor(Date.now() / 1000 + 2000)
  })
  const encodeText = header + "." + Utilities.base64Encode(claimSet, Utilities.Charset.UTF_8)
  const signature = Utilities.computeRsaSha256Signature(encodeText, ENV.PRIVATE_KEY)
  return encodeText + "." + Utilities.base64Encode(signature)
}

// 2.JWTを使ってAccess Tokenを取得
function getAccessToken(ENV, scopes) {
  const uri = "https://auth.worksmobile.com/oauth2/v2.0/token"
  const payload = {
    "assertion" : getJwt(ENV),
    "grant_type" : encodeURIComponent("urn:ietf:params:oauth:grant-type:jwt-bearer"),
    "client_id": ENV.CLIENT_ID,
    "client_secret": ENV.CLIENT_SECRET,
    "scope": scopes
    
  }
  const options = {
    "method": "post",
    "headers": {"Content-Type" : "application/x-www-form-urlencoded"},
    "payload": payload
  }
  return JSON.parse(UrlFetchApp.fetch(uri, options))
}

API 1.0との違い

getJwt()

  1. "iss": SERVER ID -> CLIENT IDに変更
  2. "sub": SERVICE_ACCOUNTを新しく指定するようになった
  3. Utilities.base64Encodeしたあと末尾を削らなくて良くなった。これは元々何で削る必要があったのか、ほんとよくわからなかったから、削らなくて良くなってせいせいした( ゚Д゚)

getAccessToken()

  1. "payload": "client_id"と"client_secret"を新たなに指定するようになった

おわりに

ここまでお付き合いいただきありがとうございました。
改めて思いましたけど、LINE WORKSの認証関係はずいぶんわかりやすくなりましたね。
認証クリアしてTokenはゲットできるようになったので、次はAPI Requestですね~。
まずはメッセージ送信からかな?Bot関係に沿って作って行こうと考えています。

ではまた!(^^)/

参考にさせていただきましたm(_ _)m

GoogleAppsScript 公式サイト
LINE WORKS Developers

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
What you can do with signing up
6