用 Google Apps Script 寫一個 LINE 登入功能:下篇 – 三大步驟

/

取得 LINE 登入的三大步驟

上篇的「前置作業」都設定完後,本篇要進入程式碼的部份了,程式碼主要是調用 API 來取得 token 跟資料。

前端調用 API 會有跨網域的問題,因此要由後端來處理,這邊用的是 Google Apps Script(以下簡稱 GAS)。LINE 的說明文件是推薦 Heroku,另外這邊也推薦用 Google Cloud Platform。總之,就是寫 Node.js 的。

GAS 基本使用可看這篇:
Google Apps Script 基本使用:跨網域 AJAX、接 Firebase

GCP 的使用可看這篇:
用 Google Cloud Platform(GCP)建 Node.js 網站

有了執行 code 的工具,接下來就是要寫 code 了。

整理一下請使用者用 LINE 登入,並取得公開資料的三個步驟如下圖:

LINE登入並取得資料的三大步驟(點圖開新視窗)
LINE 登入並取得資料的三大步驟(點圖開新視窗)
  1. 產出一個讓使用者點擊的 LINE 網址
  2. 拿 LINE 網址回傳的授權碼,調用 API 取得 token
  3. 拿 token 調用 API 取得使用者的公開資料

以下就開始對這三個步驟做點筆記。


1 產出一個讓使用者點擊的 LINE 網址

  • 1-1 用 https://access.line.me/oauth2/v2.1/authorize 加上參數成為一個連結
  • 1-2 使用者進到連結,LINE 會判斷是否登入過開啟不同頁面
  • 1-3 使用者從 LINE 的頁面登入後,LINE 會轉址到 redirect_uri 填的網址,並帶上 codestate 這兩個參數

這步卡了最久,因為一直以為是要調用 API,但試著 GET、POST,回來的都是完整的 HTML 內容,後來是 Google 到了 這篇,才發現,啊,根本就不是 API,而是一個單純的連結,只要讓使用者點擊連結到 LINE 的頁面,是否登入 LINE 會判斷。

既然只是一個單純的連結,那們們就生出連結就行,連結的架構如下:

這是廣告,點擊一下可以幫本站多個一點點的廣告收入,謝謝

這邊為了閱讀上好看,所以每個參數用成一行,實際使用時請整個連結是一行,官方給的範例是這樣:

https://access.line.me/oauth2/v2.1/authorize?response_type=code&client_id=1234567890&redirect_uri=https%3A%2F%2Fexample.com%2Fauth&state=12345abcde&scope=openid%20profile&nonce=09876xyz

以下筆記各參數要填的東西。

response_type

這個是使用者登入後,請LINE回傳的東西,固定填「code」(授權碼)。

client_id

就是上篇 建立 Channel 後,後台顯示的 Channel ID。

redirect_uri

就是上篇在 Channel 後台,LINE Login 頁籤 裡填入的 Callback URL。

如果這邊寫的值,跟 Callback URL 不一樣,即便使用者登入了也會報錯,LINE 不會回傳資料。

state

這個是可以填我們自己想要的驗證碼,使用者在登入後,LINE 會回傳 code、state 這兩個參數,state 的值就是我們在這邊寫入的,可以判斷當 state 回來的值跟我們寫入的是一樣時,才執行某個 function,防止被大量登入變成攻擊。

scope

想要取得的公開資料,可以填三個值:profile、openid、email。

可以一次三個全取,用 %20 連接,像這樣:

這是廣告,點擊一下可以幫本站多個一點點的廣告收入,謝謝

...&scope=openid%20profile%20email

連結建立完後,就可以讓使用者點擊連結連到 LINE,LINE 會判斷使用者是否連動過,桌機版的話會給出不同頁面,手機上的話如果連動過就會直接回傳 code 跟 state 了,不會要求再次登入。

拿 Let’s Write 訂閱電子報來載圖,桌機版如下:

1 先登入LINE
1 先登入 LINE
2 確認授權
2 確認授權

如果曾經授權過,之後就只會要求登入,不會再要授權。

使用者登入 LINE 並且有授權連動,LINE 就會把頁面轉址到 redirect_uri 的那個網址,本篇是用 GAS 的,redirect_uri 填的是 GAS 發佈後產的網址,因此這一步最後會收到的網址如下:

https://script.google.com/macros/s/xxxxxxxxxxxxxxxxxxxxxxxxx/exec?code=xdl9dGKAT242TWQq0koa&state=abc

可以看到確認帶了二個參數:code、state。

state 這邊亂填,就填了 abc,所以這邊回來的也就寫 abc。

code 就是授權碼,下一步就是要拿 code 的值去調用 API 要 token。

code 一次只能保留 10 分鐘,10 分鐘過後這組 code 就沒用了。

這段介紹的參數都是文件中規定必填的參數,完整的參數可以看 官方文件


2 拿 LINE 網址回傳的授權碼,調用 API 取得 token

  • 2-1 拿 code 去調用 https://api.line.me/oauth2/v2.1/token
  • 2-2 API 回傳的資料會有一個 id_token,這個就是下一步取使用者資料要用的

上一步我們拿到了 code(授權碼),這一步就是拿這個 code 去調用取 token 的 API。

這一段也卡了一陣子,因為官方文件中是用 crul 去做示範的,而 August 在寫的時候是用 GAS,同樣是 POST,但寫法不同。

官方文件的 Demo 換用 GAS 是寫成這樣

調用 API 時有幾個必要的參數,這邊寫一下:

grant_type

固定填 authorization_code

code

這是上一步取得的 code,因為值會附在回來的網址中,所以在 GAS 就用 e.parameter.code 來取得。

redirect_uri

跟第一步一樣是填要轉址的網址,一樣要跟 Channel 的 Callback URL 相同。

這邊用 GAS,所以一樣是填發佈後的網址。

client_id

跟第一步一樣,填 Channel ID。

client_secret

在上篇中有提到,建完 Channel 後,可以從後台看到 Channel ID、Channel secret。client_secret 就是填 Channel secret。

POST API 後,回傳的值有六個:access_token、expires_in、id_token、refresh_token、scope、token_type。

我們只需要其中的 id_token,拿 id_token 就可以進到下一步取資料了。

如果想了解其他的值代表什麼意思,可以看 官方說明文件


3 拿 token 調用 API 取得使用者的公開資料

  • 3-1 拿 id_token 調用 Social API
  • 3-2 回來的值就會包含 name、picture、email

這一步就是拿剛剛得到的 id_token,去調用 Social API,就可以取得使用者的名稱、大頭照、email。主要是看第一步建立網址時,scope 裡寫了什麼,如果沒寫 email,那就不會有 email。

官方說明文件的範例一樣是用 curl:

curl -v -X POST 'https://api.line.me/oauth2/v2.1/verify' \
 -d 'id_token=eyJraWQiOiIxNmUwNGQ0ZTU2NzgzYTc5MmRjYjQ2ODRkOD...'

August 一樣改寫成用 GAS 來調用 API:

調用 Social API 只有兩個參數是必填:

id_token

就是上一步取得的 id_token。

client_id

就是 Channel ID。

API 回傳的值會像這樣:

{
    "iss": "https://access.line.me",
    "sub": "U1234567890abcdef1234567890abcdef",
    "aud": "1234567890",
    "exp": 1504169092,
    "iat": 1504263657,
    "nonce": "0987654asdf",
    "amr": [
        "pwd",
        "linesso",
        "lineqr"
    ],
    "name": "Taro Line",
    "picture": "https://sample_line.me/aBcdefg123456",
    "email": "taro.line@example.com"
}

最下面三個的 name、picture、email,就是我們最後要取得的資料。

sub 是指每一位使用者的獨立 ID。

如果想了解每一個值的意思,可看 官方說明文件


三大步驟的完整程式碼

扣掉第一部是單純的連結,August 附上實作可取得使用者公開資料的程式碼。

程式碼的最後是把資料傳到 Firebase 上做儲存,因此有 在 GAS 引入 Firebase 的功能。

最後實際的使用結果,可以直接掃 QR code,掃完後也順便訂閱了 Let’s Write 的電子報了。但…目前還沒有寫一個電子報的版出來,所以前期還是會以 LINE 的推播為主,也歡迎加入~

請掃描(手機就直接點)這 QR code 訂閱電子報並加入 Let’s Write 的 LINE 官方帳號:

2020.04.02 更新:
最近 August 研究了 Auth0 的註冊會員 方式,裡面也可以直接用 LINE 登入,因此本站由今天開始改採用了 Auth0 來註冊、登入會員。以下的 QRcode 連結改為 Auth0 的登入。

訂閱電子報並加入Let's Write的LINE官方帳號
訂閱電子報並加入 Let’s Write會員

參考資源

Integrating LINE Login with your web app

Verify ID token

Class UrlFetchApp

Really strange error post with google script

Summary
用 Google Apps Script 寫一個 LINE 登入功能:下篇 – 三大步驟
Article Name
用 Google Apps Script 寫一個 LINE 登入功能:下篇 – 三大步驟
Description
本篇大綱:取得 LINE 登入的三大步驟。1 產出一個讓使用者點擊的 LINE 網址。2 拿 LINE 網址回傳的授權碼,調用 API 取得 token。3 拿 token 調用 API 取得使用者的公開資料。三大步驟的完整程式碼。參考資源。
Augustus
Let's Write
Let's Write
https://letswrite.tw/wp-content/uploads/2020/08/logo_512.jpg

隨選筆記文

Vue

Nuxt.js 引用 Firebase SDK

API

切詞工具結巴 Jeiba 優化標籤關鍵字

Front-End

用原生 JS 做一個簡單的手風琴 Accordion / Collapse 功能

Google Others

用 GCP 建立 Cloud Functions

API

GitHub API:建立 Issue、Comment – API、Personal access tokens

Google Others

Google Optimize A/B Testing 使用筆記

Apps Script Google

用 Google Apps Script 取得 Google Sheets / Excel 資料

Vue

Nuxt.js 一些好用的設定

PWA

PWA學習筆記-6:實際使用整體流程範例

Firebase Google

Firebase Performance 使用筆記

以下是留言,但關於留言的部份必需先讓你們知道:

本站的文章都是 August 因為覺得有趣,才會實作並整理成筆記文而後進行發表。

如果留言是希望把 Demo 改成「你想要」的樣子,或是把功能改成「符合你需求」的樣子,

Sorry~ 除非那修改是 August 也有興趣的,不然不會幫你們寫程式去面對工作或是交作業。

未來這類的留言不會再主動回覆。😎

另外,公開信箱是為了讓金流驗證用,

因為之前遇過幾次回信協助解決問題後,對方卻一聲謝謝也沒有,就這樣拿去幫工作交差。

因此決定不再回覆信件,有疑問就利用留言功能囉。