Introduction
# ==============================
# 架構圖
# ==============================
# |
# |-----------------|
# | Nginx |
# | SSL Termination |
# |_________________|
# |
# |
# |---------|
# | NOP | |----------|
# | |-----| MySQL |
# |_________| |__________|
# |
# ----------------
# | |
# |---------| |---------|
# | Micro | | Micro |
# | Service | | Service | ...
# |_________| |_________|
# ==============================
GoRvp 作為 OAuth2 認證伺服器,以及反向代理伺服器的功能,連線經過 GoRvp,若認證通過才會被導向至後端的 API 伺服器。
Identity provider
由於 GoRvp 本身不管理帳號資料,在帳號與密碼的驗證需要透過 identity server 提供, 因此在設定檔有 identity_endpoint 的欄位可以設定 identity server 的 URL。
GoRvp 與 identity server 使用 JWT + JWE 交換使用者資訊。
User Login
HTTP Request
一般使用者
POST http://api.example.com/authorize
管理者
POST http://api.example.com/admin/authorize
Parameters (JSON)
Parameter | Description |
---|---|
username | 帳號 |
password | 密碼 |
Response Parameters
Parameter | Description |
---|---|
access_token | access token |
expiry | expiry date |
token_type | token type |
Example request
http -v --form POST https://api.example.com/auth \
password="foobar" \
username="peter
POST /auth HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: api.example.com
password=foobar&username=peter
Example response
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI3ZDZhYTcxMy03ZDc3LTQzN2EtYTA5Ny0zNTUyZDVlZWIwMzEiLCJjbmkiOiJkOTJjNWM1OS02ZjZhLTQyNWQtODY3Ny1mMDUzNjk0YzUwMGIiLCJleHAiOjE0NzY2Mzc3NDksImlhdCI6MTQ3MTQ1Mzc0OSwiaXNzIjoiaHR0cHM6Ly9hcGkuZ29ydnAuZGV2IiwianRpIjoiZmZjY2QyNzktYTg4Zi00ODdhLTk4ZjQtZWI1NTg2ZDMxMGQwIiwibmJmIjotNjIxMzU1OTY4MDAsInNjbyI6InBhc3N3b3JkIiwic3ViIjoicGV0ZXIifQ.YojIVY_P8yijcVQjpw1J50JnujFkupFB1tXx19IUhaUtPt5-yH2idGFfE27RDJMAFRHcvm0ydqfIS1ueLqE9_ieroR8IGpi9SHqxjGPI4Zo0vUx_jFFTPhdYQuCWIfNxNcBrZNqpTmkYWj4SW8EsB1qhiORAryKGKlGvEUsS-aq6VjxSRVFDUhUwNU4ZXi2C",
"expiry": "2016-10-17T01:09:09.9836053+08:00",
"token_type": "bearer"
}
Admin API
App type | OAuth flow |
---|---|
android | Implicit flow |
web_app (frontend) | Implicit flow |
web_baclend (backend) | Explicit flow |
Create an Android Client
HTTP Request
POST https://api.example.com/admin/client
Parameters (JSON)
Parameter | Description |
---|---|
app_type | 固定為 android |
key_hash | 簽署此 app 的 sha1 hash |
name | 名稱 |
package_name | package name |
scope | 授予的權限 |
Response Parameters
回傳的 secret 可以忽略,在 Android 目前沒有用到。
Parameter | Description |
---|---|
id | client id |
secret | client secret |
Example request
http -v POST https://api.example.com/admin/client \
app_type=android \
key_hash=4b9312cb6558ea60d8d97cdc735746c85172dc3c \
name=example \
package_name=com.example.third_party_app \
scope:='[ { "name": "grade", "required": true }, { "name": "class_schedule", "required": true }, { "name": "event", "required": true }, { "name": "offline", "required": true } ]' \
Authorization:"Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI1MzJjNDRjZS1hMDQwLTQ5YmMtYWJmOS02MjcxYzY5YmNkYmMiLCJjbmkiOiI2NDc1MjA1Yy04MTYxLTRmNDItYTIzMC0zMjQxYmFiOTY4OGEiLCJleHAiOjEuNDg1MDcxMDg0ZSswOSwiaWF0IjoxLjQ3OTg4NzA4NGUrMDksImlzcyI6Imh0dHBzOi8vYXBpLmdvcnZwLmRldiIsImp0aSI6ImViYjUyYTUzLTliYzQtNDg5Ni05ZTRmLTU3MTlhNjA5ZjlmZSIsIm5iZiI6LTYuMjEzNTU5NjhlKzEwLCJzY28iOiJhZG1pbiIsInN1YiI6InBldGVyIn0.wNFbF95ruZHKTZIw7RjFgTMyjMtyXTX7oKU_hl2OdrVmvyew5KgIfofzNlxQBKPph0b9i7IEDVtYDkQHBi_Ny9UrodMpL0WQ0Y-Nj9r7TQm_zl8UGwXFeHSubf2dYNthAgLMPnEEoy_byv5DLfw73I-lCf8aVjkkWnYyHGHGUfeFKvSsgEKOJRqHQl67ti5u"
POST /admin/client HTTP/1.1
Content-Type: application/json
Host: api.example.com
{
"app_type": "android",
"key_hash": "4b9312cb6558ea60d8d97cdc735746c85172dc3c",
"name": "third-party",
"package_name": "com.example.third_party_app",
"scope": [
{
"name": "grade",
"required": true
},
{
"name": "class_schedule",
"required": true
},
{
"name": "event",
"required": true
},
{
"name": "offline",
"required": true
}
]
}
Example response
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "067748c1-9cc4-47d5-b337-0f452f3801f3",
"secret": "0c931a6eecc26f13eba386cd92dae809"
}
Create a non-confidential client
HTTP Request
POST https://api.example.com/admin/client
Parameters (JSON)
Parameter | Description |
---|---|
app_type | 固定為 web_app |
redirect_uri | 重導向的 URI |
name | 名稱 |
scope | 授予的權限 |
Response Parameters
回傳的 secret 可以忽略,在 Android 目前沒有用到。
Parameter | Description |
---|---|
id | client id |
secret | client secret |
Example request
http -v POST https://api.example.com/admin/client \
app_type=web_app \
redirect_uri="http://www.example.com/callback" \
name=example \
scope:='[ { "name": "grade", "required": true }, { "name": "class_schedule", "required": true }, { "name": "event", "required": true }, { "name": "offline", "required": true } ]' \
Authorization:"Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI1MzJjNDRjZS1hMDQwLTQ5YmMtYWJmOS02MjcxYzY5YmNkYmMiLCJjbmkiOiI2NDc1MjA1Yy04MTYxLTRmNDItYTIzMC0zMjQxYmFiOTY4OGEiLCJleHAiOjEuNDg1MDcxMDg0ZSswOSwiaWF0IjoxLjQ3OTg4NzA4NGUrMDksImlzcyI6Imh0dHBzOi8vYXBpLmdvcnZwLmRldiIsImp0aSI6ImViYjUyYTUzLTliYzQtNDg5Ni05ZTRmLTU3MTlhNjA5ZjlmZSIsIm5iZiI6LTYuMjEzNTU5NjhlKzEwLCJzY28iOiJhZG1pbiIsInN1YiI6InBldGVyIn0.wNFbF95ruZHKTZIw7RjFgTMyjMtyXTX7oKU_hl2OdrVmvyew5KgIfofzNlxQBKPph0b9i7IEDVtYDkQHBi_Ny9UrodMpL0WQ0Y-Nj9r7TQm_zl8UGwXFeHSubf2dYNthAgLMPnEEoy_byv5DLfw73I-lCf8aVjkkWnYyHGHGUfeFKvSsgEKOJRqHQl67ti5u"
POST /admin/client HTTP/1.1
Content-Type: application/json
Host: api.example.com
{
"app_type": "web_app",
"name": "example",
"redirect_URI": "http://www.example.com/callback",
"scope": [
{
"name": "grade",
"required": true
},
{
"name": "class_schedule",
"required": true
},
{
"name": "event",
"required": true
},
{
"name": "offline",
"required": true
}
]
}
Example response
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "ff3c35b8-a207-4a78-8e8e-2162dbadfc47",
"secret": "db3d216b2a2cb599249f5d3403d4d87c"
}
Create a confidential client
HTTP Request
POST https://api.example.com/admin/client
Parameters
Parameter | Description |
---|---|
app_type | 固定為 web_backend |
redirect_URI | 重導向的 URI |
name | 名稱 |
scope | 授予的權限 |
Response Parameters
回傳的 secret 可以忽略,在 Android 目前沒有用到。
Parameter | Description |
---|---|
id | client id |
secret | client secret |
Example request
http -v POST https://api.example.com/admin/client \
app_type=web_backend \
redirect_URI="http://www.example.com/callback" \
name=example \
scope:='[ { "name": "grade", "required": true }, { "name": "class_schedule", "required": true }, { "name": "event", "required": true }, { "name": "offline", "required": true } ]' \
Authorization:"Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI1MzJjNDRjZS1hMDQwLTQ5YmMtYWJmOS02MjcxYzY5YmNkYmMiLCJjbmkiOiI2NDc1MjA1Yy04MTYxLTRmNDItYTIzMC0zMjQxYmFiOTY4OGEiLCJleHAiOjEuNDg1MDcxMDg0ZSswOSwiaWF0IjoxLjQ3OTg4NzA4NGUrMDksImlzcyI6Imh0dHBzOi8vYXBpLmdvcnZwLmRldiIsImp0aSI6ImViYjUyYTUzLTliYzQtNDg5Ni05ZTRmLTU3MTlhNjA5ZjlmZSIsIm5iZiI6LTYuMjEzNTU5NjhlKzEwLCJzY28iOiJhZG1pbiIsInN1YiI6InBldGVyIn0.wNFbF95ruZHKTZIw7RjFgTMyjMtyXTX7oKU_hl2OdrVmvyew5KgIfofzNlxQBKPph0b9i7IEDVtYDkQHBi_Ny9UrodMpL0WQ0Y-Nj9r7TQm_zl8UGwXFeHSubf2dYNthAgLMPnEEoy_byv5DLfw73I-lCf8aVjkkWnYyHGHGUfeFKvSsgEKOJRqHQl67ti5u"
POST /admin/client HTTP/1.1
Content-Type: application/json
Host: api.example.com
{
"app_type": "web_backend",
"name": "example",
"redirect_URI": "http://www.example.com/callback",
"scope": [
{
"name": "grade",
"required": true
},
{
"name": "class_schedule",
"required": true
},
{
"name": "event",
"required": true
},
{
"name": "offline",
"required": true
}
]
}
Example response
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "4231b40a-c40e-4e66-8fdf-eb351eeeb081",
"secret": "2f5b59cba286ddb9abeb439cb59757cd"
}
List clients
列出所有第三方應用程式
HTTP Request
GET https://api.example.com/clients
Example request
http -v GET https://api.example.com/admin/clients \
Authorization:"Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI1MzJjNDRjZS1hMDQwLTQ5YmMtYWJmOS02MjcxYzY5YmNkYmMiLCJjbmkiOiI2NDc1MjA1Yy04MTYxLTRmNDItYTIzMC0zMjQxYmFiOTY4OGEiLCJleHAiOjEuNDg1MDcxMDg0ZSswOSwiaWF0IjoxLjQ3OTg4NzA4NGUrMDksImlzcyI6Imh0dHBzOi8vYXBpLmdvcnZwLmRldiIsImp0aSI6ImViYjUyYTUzLTliYzQtNDg5Ni05ZTRmLTU3MTlhNjA5ZjlmZSIsIm5iZiI6LTYuMjEzNTU5NjhlKzEwLCJzY28iOiJhZG1pbiIsInN1YiI6InBldGVyIn0.wNFbF95ruZHKTZIw7RjFgTMyjMtyXTX7oKU_hl2OdrVmvyew5KgIfofzNlxQBKPph0b9i7IEDVtYDkQHBi_Ny9UrodMpL0WQ0Y-Nj9r7TQm_zl8UGwXFeHSubf2dYNthAgLMPnEEoy_byv5DLfw73I-lCf8aVjkkWnYyHGHGUfeFKvSsgEKOJRqHQl67ti5u"
GET /connections/applications HTTP/1.1
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI1MzJjNDRjZS1hMDQwLTQ5YmMtYWJmOS02MjcxYzY5YmNkYmMiLCJjbmkiOiI2NDc1MjA1Yy04MTYxLTRmNDItYTIzMC0zMjQxYmFiOTY4OGEiLCJleHAiOjEuNDg1MDcxMDg0ZSswOSwiaWF0IjoxLjQ3OTg4NzA4NGUrMDksImlzcyI6Imh0dHBzOi8vYXBpLmdvcnZwLmRldiIsImp0aSI6ImViYjUyYTUzLTliYzQtNDg5Ni05ZTRmLTU3MTlhNjA5ZjlmZSIsIm5iZiI6LTYuMjEzNTU5NjhlKzEwLCJzY28iOiJhZG1pbiIsInN1YiI6InBldGVyIn0.wNFbF95ruZHKTZIw7RjFgTMyjMtyXTX7oKU_hl2OdrVmvyew5KgIfofzNlxQBKPph0b9i7IEDVtYDkQHBi_Ny9UrodMpL0WQ0Y-Nj9r7TQm_zl8UGwXFeHSubf2dYNthAgLMPnEEoy_byv5DLfw73I-lCf8aVjkkWnYyHGHGUfeFKvSsgEKOJRqHQl67ti5u
Host: api.example.com
Example response
HTTP/1.1 200 OK
Content-Type: application/json
{
"name": "tecccccst",
"app_type": "web_app",
"scopes": [
{
"name": "grade",
"required": true
},
{
"name": "class_schedule",
"required": true
},
{
"name": "event",
"required": true
}
],
"trusted": false,
"public": false,
"redirect_uri": "http://localhost/callback",
"start_activity": "",
"package_name": "",
"key_hash": ""
}
Update client
修改第三方應用程式,可以部份更改 (partial),但不允許變更 app type
HTTP Request
PATCH https://api.example.com/admin/client/:id
Example request
http -v PATCH
redirect_uri="http://www.example.com/callback" \
name=example \
scope:='[ { "name": "grade", "required": true }, { "name": "offline", "required": true } ]' \
Authorization:"Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI1MzJjNDRjZS1hMDQwLTQ5YmMtYWJmOS02MjcxYzY5YmNkYmMiLCJjbmkiOiI2NDc1MjA1Yy04MTYxLTRmNDItYTIzMC0zMjQxYmFiOTY4OGEiLCJleHAiOjEuNDg1MDcxMDg0ZSswOSwiaWF0IjoxLjQ3OTg4NzA4NGUrMDksImlzcyI6Imh0dHBzOi8vYXBpLmdvcnZwLmRldiIsImp0aSI6ImViYjUyYTUzLTliYzQtNDg5Ni05ZTRmLTU3MTlhNjA5ZjlmZSIsIm5iZiI6LTYuMjEzNTU5NjhlKzEwLCJzY28iOiJhZG1pbiIsInN1YiI6InBldGVyIn0.wNFbF95ruZHKTZIw7RjFgTMyjMtyXTX7oKU_hl2OdrVmvyew5KgIfofzNlxQBKPph0b9i7IEDVtYDkQHBi_Ny9UrodMpL0WQ0Y-Nj9r7TQm_zl8UGwXFeHSubf2dYNthAgLMPnEEoy_byv5DLfw73I-lCf8aVjkkWnYyHGHGUfeFKvSsgEKOJRqHQl67ti5u"
PATCH /admin/client/fa53c1ae-632f-4631-a2c7-3f37907c0951 HTTP/1.1
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI1MzJjNDRjZS1hMDQwLTQ5YmMtYWJmOS02MjcxYzY5YmNkYmMiLCJjbmkiOiI2NDc1MjA1Yy04MTYxLTRmNDItYTIzMC0zMjQxYmFiOTY4OGEiLCJleHAiOjEuNDg1MDcxMDg0ZSswOSwiaWF0IjoxLjQ3OTg4NzA4NGUrMDksImlzcyI6Imh0dHBzOi8vYXBpLmdvcnZwLmRldiIsImp0aSI6ImViYjUyYTUzLTliYzQtNDg5Ni05ZTRmLTU3MTlhNjA5ZjlmZSIsIm5iZiI6LTYuMjEzNTU5NjhlKzEwLCJzY28iOiJhZG1pbiIsInN1YiI6InBldGVyIn0.wNFbF95ruZHKTZIw7RjFgTMyjMtyXTX7oKU_hl2OdrVmvyew5KgIfofzNlxQBKPph0b9i7IEDVtYDkQHBi_Ny9UrodMpL0WQ0Y-Nj9r7TQm_zl8UGwXFeHSubf2dYNthAgLMPnEEoy_byv5DLfw73I-lCf8aVjkkWnYyHGHGUfeFKvSsgEKOJRqHQl67ti5u
Host: api.example.com
{
"name": "example",
"redirect_URI": "http://www.example.com/callback",
"scope": [
{
"name": "grade",
"required": true
},
{
"name": "offline",
"required": true
}
]
}
Example response
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "fa53c1ae-632f-4631-a2c7-3f37907c0951",
"created_at": "2016-11-21T17:23:15.063200935+08:00",
"updated_at": "2016-11-23T00:17:48.087843308+08:00",
"name": "example",
"app_type": "web_app",
"scopes": [
{
"name": "grade",
"required": true
},
{
"name": "offline",
"required": true
}
],
"trusted": false,
"public": true,
"redirect_uri": "http://www.example.com/callback",
"start_activity": "",
"package_name": "",
"key_hash": ""
}
Delete client
刪除第三方應用程式
HTTP Request
DELETE https://api.example.com/admin/client/:id
Query Parameters
Parameter | Description |
---|---|
id | client ID |
Example request
http -v DELETE https://api.example.com/admin/client/a3838257-6d8b-400e-beab-45d3420c38ea \
Authorization:"Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI1MzJjNDRjZS1hMDQwLTQ5YmMtYWJmOS02MjcxYzY5YmNkYmMiLCJjbmkiOiI2NDc1MjA1Yy04MTYxLTRmNDItYTIzMC0zMjQxYmFiOTY4OGEiLCJleHAiOjEuNDg1MDcxMDg0ZSswOSwiaWF0IjoxLjQ3OTg4NzA4NGUrMDksImlzcyI6Imh0dHBzOi8vYXBpLmdvcnZwLmRldiIsImp0aSI6ImViYjUyYTUzLTliYzQtNDg5Ni05ZTRmLTU3MTlhNjA5ZjlmZSIsIm5iZiI6LTYuMjEzNTU5NjhlKzEwLCJzY28iOiJhZG1pbiIsInN1YiI6InBldGVyIn0.wNFbF95ruZHKTZIw7RjFgTMyjMtyXTX7oKU_hl2OdrVmvyew5KgIfofzNlxQBKPph0b9i7IEDVtYDkQHBi_Ny9UrodMpL0WQ0Y-Nj9r7TQm_zl8UGwXFeHSubf2dYNthAgLMPnEEoy_byv5DLfw73I-lCf8aVjkkWnYyHGHGUfeFKvSsgEKOJRqHQl67ti5u"
DELETE /admin/client/a3838257-6d8b-400e-beab-45d3420c38ea HTTP/1.1
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI1MzJjNDRjZS1hMDQwLTQ5YmMtYWJmOS02MjcxYzY5YmNkYmMiLCJjbmkiOiI2NDc1MjA1Yy04MTYxLTRmNDItYTIzMC0zMjQxYmFiOTY4OGEiLCJleHAiOjEuNDg1MDcxMDg0ZSswOSwiaWF0IjoxLjQ3OTg4NzA4NGUrMDksImlzcyI6Imh0dHBzOi8vYXBpLmdvcnZwLmRldiIsImp0aSI6ImViYjUyYTUzLTliYzQtNDg5Ni05ZTRmLTU3MTlhNjA5ZjlmZSIsIm5iZiI6LTYuMjEzNTU5NjhlKzEwLCJzY28iOiJhZG1pbiIsInN1YiI6InBldGVyIn0.wNFbF95ruZHKTZIw7RjFgTMyjMtyXTX7oKU_hl2OdrVmvyew5KgIfofzNlxQBKPph0b9i7IEDVtYDkQHBi_Ny9UrodMpL0WQ0Y-Nj9r7TQm_zl8UGwXFeHSubf2dYNthAgLMPnEEoy_byv5DLfw73I-lCf8aVjkkWnYyHGHGUfeFKvSsgEKOJRqHQl67ti5u
Host: api.example.com
Example response
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Third party client
Client detail
HTTP Request
GET https://api.example.com/client/:id
Query Parameters
Parameter | Description |
---|---|
id | client id |
Response Parameters
回傳的 secret 可以忽略,在 Android 目前沒有用到。
Parameter | Description |
---|---|
id | client id |
logo_url | client 的 LOGO URL |
name | client 名稱 |
scopes | client 允許要求的權限 |
Example request
http -v GET http://api.example.com/client/ff3c35b8-a207-4a78-8e8e-2162dbadfc47
GET /client/ff3c35b8-a207-4a78-8e8e-2162dbadfc47 HTTP/1.1
Host: api.example.com
Example response
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "ff3c35b8-a207-4a78-8e8e-2162dbadfc47",
"logo_url": "",
"name": "example",
"scopes": [
{
"description": "",
"display_name": "class_schedule",
"name": "class_schedule",
"required": true
},
{
"description": "",
"display_name": "event",
"name": "event",
"required": true
},
{
"description": "",
"display_name": "grade",
"name": "grade",
"required": true
},
{
"description": "",
"display_name": "offline",
"name": "offline",
"required": true
}
]
}
Grant
HTTP Request
POST https://api.example.com/oauth/authorize
Parameters (form-urlencoded)
Parameter | Description |
---|---|
client_id | 帳號 |
response_type | 這裡使用 implicit flow, 固定為 token |
scope | 要授予第三方的權限,用空格分開 |
package_name | Android APP 的 package name |
key_hash | 簽署 APP 用的 sha1 hash |
state | 隨機產生的狀態,回傳時要比對一不一樣 |
Response Parameters
回傳的 secret 可以忽略,在 Android 目前沒有用到。
Parameter | Description |
---|---|
id | client id |
access_token | access token |
refresh_token | 若有 offline 權限會回傳此欄位作為更新 access_token 用 |
scope | 獲得的權限 |
state | 在 query 帶入的 state |
token_type | 固定為 bearer |
Example request
http -v --form POST https://api.example.com/oauth \
client_id=="6b1bdd86-563d-450e-b1ca-fdd7f4c29879" \
response_type=="token" \
scope=="gorvp foo offline" \
package_name=="io.github.gorvp.third_party_app" \
key_hash=="4b9312cb6558ea60d8d97cdc735746c85172dc3c" \
state==some-random-state-foobar \
Authorization:"Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJiNGZlY2YwYS02OGI2LTRlN2ItODQyOC05YTNjOTI3Y2JhZTEiLCJjbmkiOiI0ZGU5OWM2NC03OTM3LTRlN2QtYTMzNC0wZWM4MTdlZDEwOWIiLCJleHAiOjE0NzEyMDMyOTcsImlhdCI6MTQ3MTE5OTY5NywiaXNzIjoiaHR0cHM6Ly9hcGkuZ29ydnAuZGV2IiwianRpIjoiMTY2OWU4YjQtZWJhYi00MmI3LWEyNTctM2NjNTg5NTM4OThkIiwibmJmIjotNjIxMzU1OTY4MDAsInNjbyI6InBhc3N3b3JkIiwic3ViIjoicGV0ZXIifQ.tDM385RkwYrJNF7D27YbHKufwxYMLC9GjIKMr3JkwBCeuzK_1jIE-Dmex-M3MX9T0lsBHwbWo06BwRa3mT0htJUK-8jO7bGVfzUX1XzVf_Wr7xDrIAaFsZOwaDowoKNUYbES8cB5Dx2yUJ1tajH8RcT-IZUTsmITdFH99rFmLp-4mFwU4qv8h_LJ12MM-E5B"
GET /oauth?client_id=93d74867-9e37-47c3-964a-cc23b5497711&response_type=token&scope=grade+class_schedule+event+offline&package_name=com.example.third_party_app&key_hash=4b9312cb6558ea60d8d97cdc735746c85172dc3c&state=some-random-state HTTP/1.1
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI3ZDZhYTcxMy03ZDc3LTQzN2EtYTA5Ny0zNTUyZDVlZWIwMzEiLCJjbmkiOiJkOTJjNWM1OS02ZjZhLTQyNWQtODY3Ny1mMDUzNjk0YzUwMGIiLCJleHAiOjE0NzY2MzcxMDMsImlhdCI6MTQ3MTQ1MzEwMywiaXNzIjoiaHR0cHM6Ly9hcGkuZ29ydnAuZGV2IiwianRpIjoiNjQwMmNkNDMtMGIyZC00Y2U5LWFkZDEtOGUyZmZlODY4ODY1IiwibmJmIjotNjIxMzU1OTY4MDAsInNjbyI6InBhc3N3b3JkIiwic3ViIjoicGV0ZXIifQ.nkmdqiR4zpyNPZMAlQ6p2ESZVjRbQMZIKeTyIdx_jzDITwhwopjyXgwV72QSuG_UuKTN3mv1MVJFQZ8TJy7KXZgQ0qi_lUmXqoiShTUdz-6dvQyWs_yRddZQ3ZBe7eBD8DtZq0w48SNZJrXLrAtvD-sHA65uDs42C9gyNXKpPkxHAEMrTJBDthE48OzSEbTZ
Host: api.example.com
Example response
HTTP/1.1 302 Found
Location: http://localhost#access_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI5M2Q3NDg2Ny05ZTM3LTQ3YzMtOTY0YS1jYzIzYjU0OTc3MTEiLCJjbmkiOiIxZmYxNGQ5My00OGU3LTQyMGQtOTI1Yy0xMjhmNWE4ODM0MjQiLCJleHAiOjE0NzY2NDA1NDYsImlhdCI6MTQ3MTQ1NjU0NiwiaXNzIjoiaHR0cHM6Ly9hcGkuZ29ydnAuZGV2IiwianRpIjoiOTIzNTI0NTItZTcxMy00OWQyLTgzYmMtNzdkYjI4YWJlNTI2IiwibmJmIjotNjIxMzU1OTY4MDAsInNjbyI6ImdyYWRlIGNsYXNzX3NjaGVkdWxlIGV2ZW50IG9mZmxpbmUiLCJzdWIiOiJwZXRlciJ9.YpoWC01cXbZg5jxOS_KIAP8LJoVlLQXb-Op07yrvdfEMxH9XjxhGEL58H4h3a2_1VizpdReogtG1Z9lyIv5QirqtAEKq8qtmQ33xaskKpSXfVNxmudEw_hJkQgeTL0s8vbzP5_W3XlyKS1hzkpGrO87ZkdJjjG1x_Xg7xuNplm6LlEN9uHyzKbUUfaocMW72&expires_in=5184000&refresh_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI5M2Q3NDg2Ny05ZTM3LTQ3YzMtOTY0YS1jYzIzYjU0OTc3MTEiLCJjbmkiOiIxZmYxNGQ5My00OGU3LTQyMGQtOTI1Yy0xMjhmNWE4ODM0MjQiLCJleHAiOjE0ODcwMDg1NDYsImlhdCI6MTQ3MTQ1NjU0NiwiaXNzIjoiaHR0cHM6Ly9hcGkuZ29ydnAuZGV2IiwianRpIjoiMmZmNTVjMjctNTRhMC00OWYwLTk3NGQtZTc2ZjE0ZjNjNzc2IiwibmJmIjotNjIxMzU1OTY4MDAsInNjbyI6ImdyYWRlIGNsYXNzX3NjaGVkdWxlIGV2ZW50IG9mZmxpbmUiLCJzdWIiOiJwZXRlciJ9.O3afmEipZA5WZyBb3hn-Osn4h6QJrjZk5njjUjOKXiEdRGtlFwe9QyQrOJNbHC2qkteP9fRN7PaiyZX_j9fSjDphicMO8HaoKwGWplLyi2Eg2SQ_nbStBLYWjOeeMU-GVgAvqXMhh70OcUh63v4NjYk2J3KQbSqJSK_C42_GAYTFDd_jelK9SeDmsBNFYXbR&scope=grade%252Bclass_schedule%252Bevent%252Boffline&start_activity=&state=some-random-state&token_type=bearer
Token Management
Token Revocation
HTTP Request
POST https://api.example.com/token/:signature
Query Parameters
Parameter | Description |
---|---|
signature | JWT 的 signature |
Example request
http -v DELETE https://api.example.com/token/EsDyr7drNnUsaV4TA7I3BvMpuR0WLypOsESCYN1WgfIQQNxq1ij4P1BBYRWgdjJBidY5WPtMmg9FZanmYN66swEkVtl3od-7OXnUtSElyCqDdizm78k_vdraLnlqnd2rEJoZYvWSNLQxHmCkYyS9Ldvy7hAr7LHaJLIomq8Cz1F3nXE7QmFM4aPcEzBZJI7c \
Authorization:"Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI4YTdhMGQxNS1iZjZiLTRjMWEtODhjYS0yOGUzNGYyZWYyMjQiLCJjbmkiOiJhMzgzODI1Ny02ZDhiLTQwMGUtYmVhYi00NWQzNDIwYzM4ZWEiLCJleHAiOjE0NzY3MDg4MDAsImlhdCI6MTQ3MTUyNDgwMCwiaXNzIjoiaHR0cHM6Ly9hcGkuZ29ydnAuZGV2IiwianRpIjoiNDhjMmQxMjAtZTJkZS00MzQ2LWFhMWMtM2VkMzYzMzIyMTM5IiwibmJmIjotNjIxMzU1OTY4MDAsInNjbyI6InBhc3N3b3JkIiwic3ViIjoicGV0ZXIifQ.e7L-rI8b3Zja-eZQdb8IubcHQUKniadloozX-km4bgSm9WrPAyjMkAJ6frQ1JXw1ACmHAEgrCm4zzyN_I3o7mNYE6iUZ8alWOU6Z7a6NUPIyWj6-hCjSgq0axNx-gqmJ-GAxztOEGNLDe1eQNgAwyEDBc2CHL6OJ4oWoi3JYu7B1XiQnRpZ7hXV0d_HkMru7"
DELETE /token/EsDyr7drNnUsaV4TA7I3BvMpuR0WLypOsESCYN1WgfIQQNxq1ij4P1BBYRWgdjJBidY5WPtMmg9FZanmYN66swEkVtl3od-7OXnUtSElyCqDdizm78k_vdraLnlqnd2rEJoZYvWSNLQxHmCkYyS9Ldvy7hAr7LHaJLIomq8Cz1F3nXE7QmFM4aPcEzBZJI7c HTTP/1.1
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI4YTdhMGQxNS1iZjZiLTRjMWEtODhjYS0yOGUzNGYyZWYyMjQiLCJjbmkiOiJhMzgzODI1Ny02ZDhiLTQwMGUtYmVhYi00NWQzNDIwYzM4ZWEiLCJleHAiOjE0NzY3MDg4MDAsImlhdCI6MTQ3MTUyNDgwMCwiaXNzIjoiaHR0cHM6Ly9hcGkuZ29ydnAuZGV2IiwianRpIjoiNDhjMmQxMjAtZTJkZS00MzQ2LWFhMWMtM2VkMzYzMzIyMTM5IiwibmJmIjotNjIxMzU1OTY4MDAsInNjbyI6InBhc3N3b3JkIiwic3ViIjoicGV0ZXIifQ.e7L-rI8b3Zja-eZQdb8IubcHQUKniadloozX-km4bgSm9WrPAyjMkAJ6frQ1JXw1ACmHAEgrCm4zzyN_I3o7mNYE6iUZ8alWOU6Z7a6NUPIyWj6-hCjSgq0axNx-gqmJ-GAxztOEGNLDe1eQNgAwyEDBc2CHL6OJ4oWoi3JYu7B1XiQnRpZ7hXV0d_HkMru7
Host: api.example.com
Example response
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
List applications
列出所有授予權限的第三方應用程式
HTTP Request
GET https://api.example.com/connections/applications
Example request
http -v GET https://api.example.com/connections/applications \
Authorization:"Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI4YTdhMGQxNS1iZjZiLTRjMWEtODhjYS0yOGUzNGYyZWYyMjQiLCJjbmkiOiJhMzgzODI1Ny02ZDhiLTQwMGUtYmVhYi00NWQzNDIwYzM4ZWEiLCJleHAiOjE0NzY3MDg4MDAsImlhdCI6MTQ3MTUyNDgwMCwiaXNzIjoiaHR0cHM6Ly9hcGkuZ29ydnAuZGV2IiwianRpIjoiNDhjMmQxMjAtZTJkZS00MzQ2LWFhMWMtM2VkMzYzMzIyMTM5IiwibmJmIjotNjIxMzU1OTY4MDAsInNjbyI6InBhc3N3b3JkIiwic3ViIjoicGV0ZXIifQ.e7L-rI8b3Zja-eZQdb8IubcHQUKniadloozX-km4bgSm9WrPAyjMkAJ6frQ1JXw1ACmHAEgrCm4zzyN_I3o7mNYE6iUZ8alWOU6Z7a6NUPIyWj6-hCjSgq0axNx-gqmJ-GAxztOEGNLDe1eQNgAwyEDBc2CHL6OJ4oWoi3JYu7B1XiQnRpZ7hXV0d_HkMru7"
GET /connections/applications HTTP/1.1
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI4YTdhMGQxNS1iZjZiLTRjMWEtODhjYS0yOGUzNGYyZWYyMjQiLCJjbmkiOiJhMzgzODI1Ny02ZDhiLTQwMGUtYmVhYi00NWQzNDIwYzM4ZWEiLCJleHAiOjE0NzY3MDg4MDAsImlhdCI6MTQ3MTUyNDgwMCwiaXNzIjoiaHR0cHM6Ly9hcGkuZ29ydnAuZGV2IiwianRpIjoiNDhjMmQxMjAtZTJkZS00MzQ2LWFhMWMtM2VkMzYzMzIyMTM5IiwibmJmIjotNjIxMzU1OTY4MDAsInNjbyI6InBhc3N3b3JkIiwic3ViIjoicGV0ZXIifQ.e7L-rI8b3Zja-eZQdb8IubcHQUKniadloozX-km4bgSm9WrPAyjMkAJ6frQ1JXw1ACmHAEgrCm4zzyN_I3o7mNYE6iUZ8alWOU6Z7a6NUPIyWj6-hCjSgq0axNx-gqmJ-GAxztOEGNLDe1eQNgAwyEDBc2CHL6OJ4oWoi3JYu7B1XiQnRpZ7hXV0d_HkMru7
Host: api.example.com
Example response
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"client": {
"id": "8a7a0d15-bf6b-4c1a-88ca-28e34f2ef224",
"logo_url": "",
"name": "example_api",
"scopes": []
},
"id": "a3838257-6d8b-400e-beab-45d3420c38ea"
}
]
Revoke application
撤銷應用程式的存取
HTTP Request
DELETE https://api.example.com/connections/:id
Query Parameters
Parameter | Description |
---|---|
id | connection ID |
Example request
http -v DELETE https://api.example.com/connections/a3838257-6d8b-400e-beab-45d3420c38ea \
Authorization:"Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI4YTdhMGQxNS1iZjZiLTRjMWEtODhjYS0yOGUzNGYyZWYyMjQiLCJjbmkiOiJhMzgzODI1Ny02ZDhiLTQwMGUtYmVhYi00NWQzNDIwYzM4ZWEiLCJleHAiOjE0NzY3MDg4MDAsImlhdCI6MTQ3MTUyNDgwMCwiaXNzIjoiaHR0cHM6Ly9hcGkuZ29ydnAuZGV2IiwianRpIjoiNDhjMmQxMjAtZTJkZS00MzQ2LWFhMWMtM2VkMzYzMzIyMTM5IiwibmJmIjotNjIxMzU1OTY4MDAsInNjbyI6InBhc3N3b3JkIiwic3ViIjoicGV0ZXIifQ.e7L-rI8b3Zja-eZQdb8IubcHQUKniadloozX-km4bgSm9WrPAyjMkAJ6frQ1JXw1ACmHAEgrCm4zzyN_I3o7mNYE6iUZ8alWOU6Z7a6NUPIyWj6-hCjSgq0axNx-gqmJ-GAxztOEGNLDe1eQNgAwyEDBc2CHL6OJ4oWoi3JYu7B1XiQnRpZ7hXV0d_HkMru7"
DELETE /connections/a3838257-6d8b-400e-beab-45d3420c38ea HTTP/1.1
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiI4YTdhMGQxNS1iZjZiLTRjMWEtODhjYS0yOGUzNGYyZWYyMjQiLCJjbmkiOiJhMzgzODI1Ny02ZDhiLTQwMGUtYmVhYi00NWQzNDIwYzM4ZWEiLCJleHAiOjE0NzY3MDg4MDAsImlhdCI6MTQ3MTUyNDgwMCwiaXNzIjoiaHR0cHM6Ly9hcGkuZ29ydnAuZGV2IiwianRpIjoiNDhjMmQxMjAtZTJkZS00MzQ2LWFhMWMtM2VkMzYzMzIyMTM5IiwibmJmIjotNjIxMzU1OTY4MDAsInNjbyI6InBhc3N3b3JkIiwic3ViIjoicGV0ZXIifQ.e7L-rI8b3Zja-eZQdb8IubcHQUKniadloozX-km4bgSm9WrPAyjMkAJ6frQ1JXw1ACmHAEgrCm4zzyN_I3o7mNYE6iUZ8alWOU6Z7a6NUPIyWj6-hCjSgq0axNx-gqmJ-GAxztOEGNLDe1eQNgAwyEDBc2CHL6OJ4oWoi3JYu7B1XiQnRpZ7hXV0d_HkMru7
Host: api.example.com
Example response
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Errors
Response Parameters
Parameter | Description |
---|---|
error_description | error description |
error_type | error type |
status_code | http status code |
Example request
http -v GET http://api.example.com/client/client-not-exist
GET /client/client-not-exist HTTP/1.1
Host: api.example.com
Example response
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error_description": "Record not found",
"error_type": "not_found",
"status_code": 404
}