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

用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去做示範的,而Augustus在寫的時候是用GAS,同樣是POST,但寫法不同。

官方文件的Demo是這樣:

curl -X POST https://api.line.me/oauth2/v2.1/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=authorization_code' \
-d 'code=xxx' \
-d 'redirect_uri=xxx' \
-d 'client_id=xxx' \
-d 'client_secret=xxx'

這邊換用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...'

Augustus一樣改寫成用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。

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


三大步驟的完整程式碼

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

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

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

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

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

參考資源

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取得使用者的公開資料。三大步驟的完整程式碼。參考資源。上篇的「前置作業」都設定完後,本篇要進入程式碼的部份了,程式碼主要是呼API來取得token跟資料。
Augustus
Let's Write
Let's Write
Publisher Logo

留言