介接申請

  • 地址:10561 臺北市松山區八德路四段101號 (中崙高中)
  • 電話:(02)2753-5316 轉250
  • 信箱:coocservice@tp.edu.tw
  • 服務時間:週一至週五 08:00-17:00 (上班時間)

申請需提供的資料:

  1. 提供貴單位服務名稱。
  2. 提供貴單位服務的 Icon,建議寬高 200 X 200,且去背。
  3. 提供 Callback URI:
    1. 設定該網址的目的,是用於 OAuth 主機完成初步認證後,會把暫時授權碼 (Authorization Code) 送回此網址。
    2. 您可以提供多組路徑,便於開發和測試時使用。
    3. 請必須是 HTTPS 加密連線。
      例如: https://example.com/myapp/cooc_callback
  4. 提供 EntryPoint:
    1. 設定該網址的目的,是用於酷課雲使用者點擊貴單位服務時會開啟之網址。
      例如: https://example.com/myapp/entrypoint
    2. 酷課雲會將使用者當下操作的身分資訊,以 Query String 方式帶入至 EntryPoint。
      參數值如下:
      • school_type: 學制
      • school_code: 學校代碼
      • role_type: 角色
      • uuid: 若為家長身分,回傳小孩臺北市政府教育局單一身分驗證服務的識別碼;非家長身分時,則為空值
      例如: https://example.com/myapp/entrypoint?school_type=高中&school_code=000000&role_type=parent&uuid=a3ecxxxx-xxxx
    3. EntryPoint 建議做兩件事
      1. 把上述四個參數值儲存於 session 中。
      2. 轉址啟動 OAuth 授權(請見下方步驟 2)。

待申請通過後,中心會發給您這個服務專用的 Client ID / Client Secret。Client Secret 請妥善保存,且請勿於 Client 端中使用。

開啟授權網址,並傳遞正確的參數值

  1. 貴單位服務需開啟以下網址:
    https://cooc.tp.edu.tw/oauth/authorize
    ?response_type=code
    &client_id={Client ID}
    &redirect_uri={Callback URI}
    &scope=User.Info,User.Role,User.SSORole,User.IDNumber
    &state={state}
    
    例如:
    https://cooc.tp.edu.tw/oauth/authorize?response_type=code&client_id=a87370c1axxxxxxxxxxxxxxxxxx&redirect_uri=https%3A%2F%2Fexample.com%2Fmyapp%2Fcooc_callback&scope=User.Info,User.Role,User.SSORole,User.IDNumber
    參數:
    • response_type: 目前要執行的授權
    • client_id: 中心發給您的 client_id
    • redirect_uri: 授權後要接收暫時授權碼 (Authorization Code) 的網址。
      網址需與您申請的任一 Callback URI 相符合。並請將網址編碼,避免發生錯誤。
    • scope: 需向使用者取得授權的範圍
      User.Info,
      // 取得 uuid, user_name, first_name, last_name, email, email_verified
      User.Role,
      // 取得 role
      User.SSORole
      // 取得 sso_role
      User.IDNumber
      // 取得 id_number
    • state: 用於安全目的。如果設置了此參數,那麼它將在 redirect_uri 時返回給貴單位。
  2. 如果使用者已經登入酷課雲帳號(例如:從酷課雲點選開啟服務),則上述網址會繼續 OAuth 流程,並跳到下一步驟。
    如果使用尚未登入酷課雲,則瀏覽器會開啟酷課雲單一登入畫面,供使用者輸入帳號密碼登入。
  3. 認證成功後,瀏覽器會把將暫時授權碼 (Authorization Code),傳回給您指定的 Callback URI (如: https://example.com/myapp/cooc_callback)
    例如:
    https://example.com/myapp/cooc_callback?state=&code=5489489e546a4c016e9ae105f5beefe8

請使用 HTTP POST 的方式呼叫授權主機的服務,把暫時授權碼 (Authorization Code) 成短暫時間(60 min)有效的存取金鑰 (Access Token)。

POST
https://cooc.tp.edu.tw/oauth/token
請求文件
參數:
  • client_id: 中心發給您的 Client ID
  • client_secret: 中心發給您的 Client Secret
  • code: 暫時授權碼 (Authorization Code)
  • redirect_uri: 授權後要接收暫時授權碼 (Authorization Code) 的網址。
    網址需與您申請的任一 Callback URI 相符合。並請將網址編碼,避免發生錯誤。
  • grant_type: 採用的授權方式
範例 (以 Node.js 為例):
const token_url = [
  'https://cooc.tp.edu.tw/oauth/token',
  `?client_id=${Client ID}`,
  `&client_secret=${Client Secret}`,
  `&code=${Authorization Code}`,
  `&redirect_uri=${encodeURIComponent({Callback URI})}`,
  `&grant_type=authorization_code`
].join('');

request({
  method: 'POST',
  uri: token_url
}, (error, response, body) => {
  if (!error) {
    const token = JSON.parse(body.trim());

    if (!token.error) {
      req.session.access_token = token.access_token;
    }
 }
});
取得 access_token 的格式如下:
{
  "access_token": "ca8634ff3249432596c38...",
  "refresh_token": "14bd93d7308a4158bc.....",
  "expires_in": 3600,
  "token_type": "bearer",
  "id_token": "eyJhbGciOi............"
}
取得 Access Token 之後,可以選擇 4-1 或 4-2 其中一種方式來取得使用者資訊。
使用 JWT 格式解析 id_token (減少 Service 呼叫)。
  {
    "iss": "https://cooc.tp.edu.tw/",
    "sub": "77be4deb-fc3b-4ea5-849f-10404afe6783",
    "aud": "a87370c1axxxxxxxxxxxxxxxxxx",
    "exp": 1555039894,
    "iat": 1555036294,
    "auth_time": 1555036294,
    "uuid": "77be4deb-fc3b-4ea5-849f-10404afe6783",
    "user_name": "example@tp.edu.tw",
    "first_name": "example",
    "last_name": "",
    "role": ["teacher","parent"]	// role 欄位需要 User.Role 這個 scope
  }
  
GET
https://cooc.tp.edu.tw/oauth/getUserInfo
請求文件
參數:
access_token
範例:
https://cooc.tp.edu.tw/oauth/getUserInfo?access_token=313b9947739e71cb50XXXXXXXXXXXX
回覆文件
正常資料:
{
  "uuid": "77be4deb-fc3b-4ea5-849f-10404afe6783", // 酷課雲唯一識別值
  "user_name": "example@tp.edu.tw", // 帳號
  "first_name": "林大美", // 名字
  "last_name": "example", // 姓氏
  "email": "", // 電子信箱
  "email_verified": true, // 電子信箱是否已驗證
  "id_number": "A000000000", // 身分證號
  "role": ["parent", "teacher"], // 擁有的角色 teacher, student, parent
  "sso_role": [
    {
      "source": "ldap", // 登入方式 ldap: 從臺北單一登入, basic: 直接指定身份, ntpc: 從新北單一登入
      "identity": "", // 此登入方式的識別值
      "user_name": "example@tp.edu.tw", // 帳號
      "first_name": "", // 名字
      "last_name": "", // 姓氏
      "id_number": "A000000000", // 身分證號
      "last_login_time": "2019-01-01T14:38:28.62023+08:00", // 最近登入時間
      "role": [
        {
          "role_type": "parent", // 角色 teacher, student, parent
          "school_code": "000000", // 學校代碼
          "school_name": "XX高中", // 學校名稱
          "school_type": "高中", // 學制 國小, 國中, 高中, 高職
          "school_grade_year": 2, // 年級
          "school_class_name": "101", // 班級名稱
          "school_class_no": "101", // 班級號碼
          "school_seat_no": 1, // 座號
          "school_user_id": "", // 校務中的學生編號
          "school_student_number": "", // 學號
          "school_position": [], // 部門、職稱
          "child_detail": {
            "name": "林小花", // 小孩的姓名
            "identity": "", // 小孩的uuid
            "id_number": "" // 小孩的身分證號
          }
        },
        {
          "role_type": "teacher",
          "school_code": "000000",
          "school_name": "高級中學",
          "school_type": "高中",
          "school_grade_year": null,
          "school_class_name": null,
          "school_class_no": null,
          "school_seat_no": null,
          "school_user_id": "",
          "school_student_number": null,
          "school_position": [
            {
              "Dept": "教務處",
              "Title": "教學組長"
            }
          ],
          "child_detail": null
        },
      ]
    },
    {
      "source": "facebook",
      "identity": "",
      "user_name": "",
      "first_name": "",
      "last_name": "",
      "id_number": "",
      "last_login_time": "2020-03-12T12:56:05.912822+08:00",
      "role": []
    }
  ]
}
token 無效時:
{
  error: "invalid_grant",
  error_description: "The Access Token provided is invalid."
}
token 過期時:
{
  error: "invalid_grant",
  error_description: "The Access Token provided has expired."
}

經步驟 4-1 或 4-2 貴單位服務已經取得使用者資料,可根據使用者資料登入貴單位服務。

指向酷課雲當前學校角色

假如您期望開啟的頁面,與酷課雲首頁使用者當下的學校角色相同時,請務必使用 4-2 的方式取得使用者「詳細」角色資料。
從 session 中取出 EntryPoint 回傳給您的參數值 school_type, school_code, role_type, uuid
與角色資料中相互比對:
sso_role.role.school_type 比對 school_type
sso_role.role.school_code 比對 school_code
sso_role.role.role_type 比對 role_type
sso_role.child_detail.identity 比對 uuid
找出完全相同者,即是當前學校和角色資料。

GET
https://cooc.tp.edu.tw/oauth/token
?grant_type=refresh_token
&client_id=a7c46f49e498151cafd.....
&client_secret=d8f9ba01522fe1915e......
&refresh_token=35994fae448703f288.....
回覆文件
正常資料:
{
  "access_token": "ca8634ff3249432596c38...",
  "refresh_token": "14bd93d7308a4158bc.....",
  "expires_in": 3600,
  "token_type": "bearer",
  "id_token": "eyJhbGciOi............"
}
token 無效時:
{
  error: "invalid_grant",
  error_description: "The refresh token provided is invalid."
}
token 過期時:
{
  error: "invalid_grant",
  error_description: "The refresh token provided has expired."
}