背景
こんにちは。@ight です。最近いろんなサービスの OAuth2 や OpenID Connect などの認証/認可まわりを勉強しています。
今回はひょんなことから LinkedIn の OAuth2 Authentication で REST API を叩き、LinkedIn の情報を取ってくる機会があったのでやってみました。
実際アプリケーションを書くときには独自実装せずに既存のライブラリを使えば良いと思うんですが、今回はあえてパラメータを確認しながら REST API を叩くところまでやってみたいと思います。
Authenticating with OAuth 2.0 - LinkedIn Developer Network に従って進めていきます。
OAuth2 と呼んでいるのは RFC 6749 のことです。
いきなりのまとめ!
- Access Token 取得までは OAuth2 からそんなに外れてなくて、そんなにハマりどころはない
- Access Token の有効期間は60日で、Refresh Token はない
- REST API はデフォルトは
text/xml
で返却される - 様々な API を叩くためには Partnership Programs に登録し、審査を通過する必要がある!
- Client 登録が会社名とかいろいろ登録する必要があって、ちょっとダルい
様々な API を叩くためには Partnership Programs に登録し、審査を通過する必要がある
例えば、ユーザーのつながり関係を取得する Connections API (Facebook でいう Friend Edge) は r_network
scope を求められますが、実はその scope のためには LinkedIn's Partnership Programs というものに登録する必要があります。
「事前にテストできないの?」って思ったんですが、(自分の探した限りでは) テスト用の Client は見つからず、この Program に登録しないと Connections API は叩けないようでした。
じゃあ簡単に登録できるのかというとどうやらそうでもなさそうで、Frequently Asked Questions には
We aim to respond to all application inquiries within 15 days.
「15日以内を目標に、合否連絡をするよ」って感じです。15日...全然手軽じゃない...。
LinkedIn 連携を考える前には、あらかじめやりたいこととできることを吟味していた方が良さそうです。
(自分は Connections API が使いたかった...)
実際に REST API を叩くまでやってみる
Step 1 - Configuring your LinkedIn application
こちら から LinkedIn Application を登録することができます。
他社の Client 登録と違って会社の情報を登録する必要があります。今回は適当に埋めて進みます。
完了すると Client ID と Client Secret が払い出されます。メモしておきましょう。
おそらく scope の命名規則として (read/write)_(対象)
となっているようです。
前述の通り、ここでは4つまでしか選択することができません。
Step 2 — Request an Authorization Code
それでは Authorization Request を投げていきます。
$ CLIENT_ID=#先ほどメモした CLIENT ID
$ CLIENT_SECRET=#先ほどメモした CLIENT SECRET
$ REDIRECT_URI=https://localhost
$ open "https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&state=987654321&scope=r_basicprofile"
全て OAuth2 に沿ったパラメータ名ですね。よかった。
ちなみにユーザーが同意に cancel をすると error パラメータが返却されますが、OAuth2 に定義されている error code ではなく
user_cancelled_login
user_cancelled_authorize
が返ってくるようです。
Step 3 — Exchange Authorization Code for an Access Token
ついに Access Token を取得しましょう!
$ CODE=...
$ curl -X POST \
--data "grant_type=authorization_code" \
--data "code=${CODE}" \
--data "redirect_uri=https://localhost" \
--data "client_id=${CLIENT_ID}" \
--data "client_secret=${CLIENT_SECRET}" \
"https://www.linkedin.com/oauth/v2/accessToken" | jq
{
"access_token": "xxxx",
"expires_in": 5183999
}
expires_in
に+1して計算すると、60日分の Access Token になっているようです。token_type
は返ってきていませんが bearer です。
Step 4 — Make authenticated requests
いよいよ REST API を叩いてみましょう。
$ curl -X GET -H "Authorization: Bearer ${ACCESS_TOKEN}" 'https://api.linkedin.com/v1/people/~'
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
<id>XXXXXXXXXX</id>
<first-name>なまえ</first-name>
<last-name>みょうじ</last-name>
<headline>会社名がはいるよ</headline>
<site-standard-profile-request>
<url>https://www.linkedin.com/profile/view?id=_idididid&authType=name&authToken=lYnD&trk=api*a5218725*s5537155*</url>
</site-standard-profile-request>
</person>
おお、そうでした! デフォルトでは XML で返却されるんでした! ?format=json
をつけましょう!
$ curl -X GET -H "Authorization: Bearer ${ACCESS_TOKEN}" 'https://api.linkedin.com/v1/people/~?format=json'
{
"firstName": "なまえ",
"headline": "会社名がはいるよ",
"id": "XXXXXXXXXX",
"lastName": "みょうじ",
"siteStandardProfileRequest": {"url": "https://www.linkedin.com/profile/view?id=_idididid&authType=name&authToken=lYnD&trk=api*a5218725*s5537155*"}
}
なぜか最初から少しだけ成形された JSON で返ってきました。
Step 5 — Refresh your Access Tokens
To refresh an Access Token, simply go through the authorization process outlined in this document again to fetch a new token.
Refresh したかったらもういい一度このフローをやり直してね的なことが書かれてます。Refresh Token 的なのはなさそうですね。
ちなみにすでに認可済みの場合は、認可画面スキップしてくれる仕様のようです。