實做Google、Facebook、Line OAuth登入

2020/07/28

OAuth基本流程

  1. 前端前往第三方登入、授權頁
  2. 登入成功後取得AccessToken或是Code
  3. 將AccessToken或是Code發API交給後端
  4. 後端拿AccessToken或是Code跟Auth Server(Google/FB/Line)確認是否可用,並且取得基本資料(一般為Email)
  5. 依照專案需求自行決定這些基本資料如何使用

 

共同規範

  • client_id:前端發起OAuth登入時在URL要帶入的憑證
  • response_type:OAuth登入成功後要回應的類型,可使用token或code(Line登入只能使用code flow)
  • redirect_uri:前端登入成功後導向頁面,一般都需要在第三方的服務後台做設定
  • scope:權限請求
  • state:額外要多傳的資料,可以拿來做一些驗證資料傳遞,避免前端被不明來源執行OAuth登入

 

Google OAuth設定

前往Goolge API Console的憑證設定頁面

建立一個新的憑證

類型選擇OAuth用戶端ID

並且設定授權的JavaScript來源(就是網站的網域)

接著設定已授權的重新導向URI(就是redirectUri)

google.png

 

其餘設定例如同意畫面的條款、隱私權、審核等資料請自行依照專案設定

 

Facebook OAuth設定

開啟Facebook developer帳號

前往應用程式頁面

建立一個登入類型的應用程式

接著在設定>基本資料頁設定應用程式網域

fb-1.png

 

然後到商品設定頁面設定有效的OAuth重新導向URI(redirectUri)

fb-2.png

 

其餘設定例如同意畫面的條款、隱私權、審核等資料請自行依照專案設定

 

Line OAuth設定

開啟Line developer console頁面

開啟Providers頁面建立一個Provider

line-provider.png

 

接著開啟建立好的Provider建立一個新的Channel

並選擇LINE Login類型

line.png

 

大部分設定都依照專案設定即可

主要要設定App types為Web App即可

Screenshot_20200730_154409.png

 

建立完成後要另外請求取得Email權限

如果你的網站OAuth登入是打算透過Email來當帳號依據的話

這點一定要做

asdf.png

 

最後開啟LINE Login tab

設定Callback URL(redirectUri)

f.png

 

其餘設定例如同意畫面的條款、隱私權、審核等資料請自行依照專案設定

 

各家差異整理

 

服務設定的限制

例如Google會限制網域

Facebook也會限制網域但不限制開發機(localhost)

Line則是完全不擋

 

名詞差異

redirectUri

  • Google:已授權的重新導向URI
  • Facebook:有效的OAuth重新導向URI
  • Line:Callback URL

 

流程簡介(Google/Facebook)

oauth-google-facebook.png

 

流程簡介(Line)

oauth-line.png

 

關於State設定

前面有提到

從前端到授權頁然後再透過redirectUri回到網站上的OAuth處理中繼頁面

可以透過state傳參數在這個中繼頁取得state的資料

通常是以object格式做JSON.stringify即可(至少Google/Facebook是這樣做沒問題)

但是在Line的OAuth登入上

直接用JSON.stringify導向Line授權頁面

Line會直接回Bad Request錯誤

後來只好把JSON.stringify的前後{}字元拿掉

在redirectUri的中繼頁如果偵測是Line登入再接回{}這兩個字元

然後才能做JSON.parse取得state物件資料

簡單來說Line就是看URL的{}這個字元不爽

就是想辦法把這兩個符號去掉不要帶在URL就是了

用什麼格式都可以

 

導向授權頁面的query(Page Mode)

以下為導向各家授權頁面的Base URL

Google:https://accounts.google.com/o/oauth2/v2/auth

Facebook:https://www.facebook.com/v7.0/dialog/oauth

Line:https://access.line.me/oauth2/v2.1/authorize

 

接著是各家的URL query

以下先用JSON格式紀錄

最後再轉成QueryString帶在Base URL後即可

以下示範使用一個叫qs的js套件

很簡單就能將object轉成QueryString

 

Google

const baseUrl = 'https://accounts.google.com/o/oauth2/v2/auth'
let query = {
  client_id: clientKey,
  response_type: 'token',
  scope: 'openid email https://www.googleapis.com/auth/userinfo.profile',
  state: JSON.stringify({ foo: 'bar' }),
  redirect_uri: this.redirectUri,
}
const queryString = qs.stringify(query, { encode: false })
return `${baseUrl}?${queryString}`

 

Facebook

const baseUrl = 'https://www.facebook.com/v7.0/dialog/oauth'
let query = {
  client_id: clientKey,
  response_type: 'token',
  scope: 'public_profile email',
  state: JSON.stringify({ foo: 'bar' }),
  redirect_uri: this.redirectUri,
}
const queryString = qs.stringify(query, { encode: false })
return `${baseUrl}?${queryString}`

 

Line

const baseUrl = 'https://access.line.me/oauth2/v2.1/authorize'

// line登入頁如果url帶 { } 符號會400, 所以要先去掉頭尾的 { }
let stateString = JSON.stringify({ foo: 'bar' })
stateString = stateString.slice(0, -1)
stateString = stateString.substring(1)
let query = {
  client_id: clientKey,
  response_type: 'code', // line的oauth response type只接受code flow
  scope: 'profile openid email',
  state: stateString,
  redirect_uri: this.redirectUri,
}
const queryString = qs.stringify(query, {
  encode: false,
})
return `${baseUrl}?${queryString}`

 

總結

本篇介紹這三家的Oauth主流程就是那樣

其餘就是看各個專案取得AccessToken或是使用者資料之後怎麼使用

通篇看下來

就是Line最麻煩要跟別人不一樣

但有些專案如果要使用Line登入就沒辦法了

畢竟Line在台灣的市占率使用率真的是滿高的

 

Icon Credit

User: Icons made by Freepik from www.flaticon.com

Verify: Icons made by Pixel perfect from www.flaticon.com

Server: Icons made by Adib Sulthon from www.flaticon.com

Google: Icons made by Freepik from www.flaticon.com

Facebook: Icons made by Pixel perfect from www.flaticon.com

Line: Icons made by Freepik from www.flaticon.com

Profile: Icons made by Pixelmeetup from www.flaticon.com