42APIと戯れる
Getting startedしてみる
applicationの作成
42APIを使用するにはまずここからapplicationを作成する必要がある。(当たり前だけど42intraへのログインが必要)
設定項目は以下で埋めてみる
- name:
ft-api-client-test(api clientライブラリ作るときのテスト用な想定) - images: 未指定
- description: 適当
- Website: https://github.com/dai65527/ftapi (まだ非公開)
- redirect uri: https://42tokyo.jp (今は適当に)
UIDとSecretの取得
applicationが作成されるとUIDとSecretが作成されるので、.envに保存しておく。
FTAPI_UID=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
FTAPI_SECRET=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
Access Tokenの取得
curlでAccess Tokenを取得する
$ source .env
$ curl -X POST --data "grant_type=client_credentials&client_id=$FTAPI_UID&client_secret=$FTAPI_SECRET" https://api.intra.42.fr/oauth/token | jq
{
"access_token": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"token_type": "bearer",
"expires_in": 7200,
"scope": "public",
"created_at": 1632393654
}
Userの取得
取得したAccess Tokenを使ってdnakanoさんの情報を取得してみる。(docs)
$ curl -H "Authorization: Bearer $ACCESS_TOKEN" https://api.intra.42.fr/v2/users/dnakano | jq
{
"id": 76694,
"email": "dnakano@student.42tokyo.jp",
"login": "dnakano",
...
OAuth2を利用した認証フローを試してみる
Web Application Flow
Web Application Flowに沿って認可する際には、42APIの認可URIへユーザをリダイレクトさせる。
※ Web Application Flowについてはこれが分かりやすかった。
認可URI
Base URIのhttps://api.intra.42.fr/oauth/authorizeにクエリパラメータを付加して生成する。以下は例。
https://api.intra.42.fr/oauth/authorize?client_id=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef&redirect_uri=https://42tokyo.jp&response_type=code&scope=public&state=qwerty
クエリパラメータに関しては以下のとおり(詳しくはdocsを参照のこと)
- client_id: applicationのUID(最初にここで作成したやつ)
- redirect_uri: 認可後にリダイレクトする先のURI
- response_type: 帰ってくるtokenのtype。codeを指定すればOK。
- scope: 帰ってくるtokenで何にアクセスできるかを指定(application作成時で指定したscopeと同じ粒度で指定できると思われる)
- state: CSRF対策のための文字列(本番では長くて予測できない文字列を使用すること!)
認可URIにアクセスすると、よく見る認証ページにリダイレクトされる。


認証を許可すれば、redirect_uriで指定したページへリダイレクトされる。この際、以下のようにクエリパラメータにcodeとstateが付加される。
https://42tokyo.jp/?code=abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789&state=qwerty
codeを利用することで、42APIのリソースにアクセスできる。また、stateはCSRF対策としてアプリケーション側で指定したstateかどうか検証すること。
codeを使ってapiを叩く
まず、取得したcodeからaccess_tokenを取得する。
https://api.intra.42.fr/oauth/tokenにPOSTリクエストし、access_tokensを取得する。
$ curl -F grant_type=authorization_code \
-F client_id=$FTAPI_UID \
-F client_secret=$FTAPI_SECRET \
-F code=abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789 \
-F redirect_uri=https://42tokyo.jp \
-X POST https://api.intra.42.fr/oauth/token | jq
{
"access_token": "56789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234",
"token_type": "bearer",
"expires_in": 7200,
"refresh_token": "def0123456789abcdef0123456789abcdef0123456789abcdef0123456789abc",
"scope": "public",
"created_at": 1632404312
}
取得したaccess_tokenを使って取得する。
$ curl -H "Authorization: Bearer 56789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234" https://api.intra.42.fr/v2/me | jq
{
"id": 76694,
"email": "dnakano@student.42tokyo.jp",
"login": "dnakano",
...
GoでToken取得するコード
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"strings"
)
type OauthTokenResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
Scope string `json:"scope"`
CreatedAt int `json:"created_at"`
}
func main() {
value := url.Values{}
value.Set("grant_type", "client_credentials")
value.Set("client_id", "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
value.Set("client_secret", "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789")
req, err := http.NewRequest(http.MethodPost, "https://api.intra.42.fr/v2/oauth/token", strings.NewReader(value.Encode()))
if err != nil {
panic(err)
}
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
var oauthRes OauthTokenResponse
err = json.NewDecoder(res.Body).Decode(&oauthRes)
if err != nil {
panic(err)
}
fmt.Printf("%#v\n", oauthRes)
}
$ go run main.go
main.OauthTokenResponse{AccessToken:"56789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234", TokenType:"bearer", ExpiresIn:7200, Scope:"public", CreatedAt:1632548646}
Getting informations about your token
access_tokenの情報は/oauth/token/infoから見れる。
applicationのuid、secretから取得したトークンの取得例。
$ curl -H "Authorization: Bearer $FTAPI_ACCESS_TOKEN" https://api.intra.42.fr/oauth/token/info | jq
{
"resource_owner_id": null,
"scopes": [
"public"
],
"expires_in_seconds": 7080,
"application": {
"uid": "56789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234"
},
"created_at": 1632613447
}
codeから取得したtoken。resource_owner_idが入る。
$ curl -H "Authorization: Bearer $FTAPI_ACCESS_TOKEN" https://api.intra.42.fr/oauth/token/info | jq
{
"resource_owner_id": 76694,
"scopes": [
"public"
],
"expires_in_seconds": 7146,
"application": {
"uid": "56789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234"
},
"created_at": 1632617132
}
ページング処理
複数の結果を返すエンドポイントでは、ページングで結果の範囲を指定する。
doc: https://api.intra.42.fr/apidoc/guides/specification#pagination
デフォルトでは1ページ目を30項目読む
$ curl -H "Authorization: Bearer $ACCESS_TOKEN" https://api.intra.42.fr/v2/roles
...(30項目
指定の仕方
ページ数と1ページ当たりの項目数はクエリで指定できる。
page or page[number] : ページ数
per_page or page[size] : ページ当たりの数(最大100)
pageとper_pageで指定する場合
$ curl -H "Authorization: Bearer $ACCESS_TOKEN" 'https://api.intra.42.fr/v2/roles?page=4&per_page=2' | jq
[
{
"id": 32,
"name": "42Network",
"description": "42Network team"
},
{
"id": 31,
"name": "Project Session Manager",
"description": "Brobot will send you notification when a ps is updated"
}
]
page[number]とpage[size]で指定する場合
$ curl -H "Authorization: Bearer $ACCESS_TOKEN" 'https://api.intra.42.fr/v2/roles?page[number]=4&page[size]=2' | jq
[
{
"id": 32,
"name": "42Network",
"description": "42Network team"
},
{
"id": 31,
"name": "Project Session Manager",
"description": "Brobot will send you notification when a ps is updated"
}
]
ヘッダ
レスポンスヘッダに以下の情報が入ってくる。
- link: ページの先頭(first)、最後(last)、前後ページ(prev, next)へのリンク
- x-per-page: ページ当たりの項目数
- x-page: 取得したページ数
link: <https://api.intra.42.fr/v2/roles?page=1>; rel="first", <https://api.intra.42.fr/v2/roles?page=3>; rel="prev", <https://api.intra.42.fr/v2/roles?page=17>; rel="last", <https://api.intra.42.fr/v2/roles?page=5>; rel="next"
x-per-page: 2
x-page: 4
x-total: 34
フィルタのかけ方
複数の結果を返すエンドポイントでは、フィルタを指定できる。
クエリパラメタにfilter[フィルタしたい内容]=値を指定する。
以下はtokyoキャンパス(primary_campus_id=26)の生徒一覧を取得する例。
$ curl -H "Authorization: Bearer $ACCESS_TOKEN" -g 'https://api.intra.42.fr/v2/users?filter[primary_campus_id]=26'
なお、存在しないフィルタを指定すると400エラーが返ってくる。
$ curl -H "Authorization: Bearer $ACCESS_TOKEN" -g 'https://api.intra.42.fr/v2/users?filter[hoge]=fuga' | jq
{
"error": "Filter Error",
"message": "Attributes hoge doesn't exists or aren't filterables. Available filters are: id, login, email, created_at, updated_at, pool_year, pool_month, kind, status, primary_campus_id, first_name, last_name, alumni?, is_launched?, and staff?"
}
利用できるフィルタは、42apiのdocsに書いてある。
ソートの掛け方
クエリパラメタで。sort=ソートしたい属性 を指定する
idで昇順にソートする例。
$ curl -H "Authorization: Bearer $ACCESS_TOKEN" -g 'https://api.intra.42.fr/v2/users?sort=id'
ソート順を逆にしたい場合は、sort=-ソートしたい属性 のように-をつける。
$ curl -H "Authorization: Bearer $ACCESS_TOKEN" -g 'https://api.intra.42.fr/v2/users?sort=-id'
複数パラメタでソートしたい場合は、,で繋げる。
curl -H "Authorization: Bearer $ACCESS_TOKEN" -g 'https://api.intra.42.fr/v2/users?sort=kind,-login'
ソートできる属性も限られていて、それ以外だと400エラーになる。ソートできる属性はdocs参照のこと。
範囲指定の掛け方
また、クエリパラメタにrange[属性]=最小値,最大値で範囲(range)指定もかけられる。
$ curl -H "Authorization: Bearer $ACCESS_TOKEN" -g 'https://api.intra.42.fr/v2/users?range[pool_year]=2020,2021'
これも、指定できる属性は限られている。Docsの各エンドポイントのページを参照のこと。