用 Auth0 在 WordPress 上做會員註冊、登入功能

/

2020.12.06 公告:
本站於今日開始進行改版,本篇原本要放登入按鈕的地方,尚未規劃出移到哪個區塊,因此本站用 Auth0 的功能先暫停,直到找到適合的擺放位置。

自己的會員功能自己寫

在上一篇〈Auth0 Universal Login,做一個自己的會員註冊、登入功能〉中,寫了一個靜態頁面來接 Auth0 的 Universal Login。後來想想,如果要使用者從 Let’s Write 本站先到靜態頁,再從靜態頁進 Universal Login 的頁面,中間多了一步,容易造成使用者的疑惑跟跳出率增加。另外,登入後的個人資訊也無法呈現在本站上,因此決定花一點時間,把 Auth0 的會員註冊、登入功能直接搬到本站來。

Auth0 在 WordPress 上有外掛,有試用了一下,但不知道為何小工具那塊一直是空白,而且它的設定值,登入後就一定要轉到指定的頁面,無法回到點擊「登入」時的原頁,以上種種,再加上身為前端的驕傲 XD,Augustus 決定自己寫一個。

因為本站是用 WordPress 架設的,PHP 的部份 Augustus 並不會,所以本篇是直接用 JavaScript 來接 Auth0 的 API。

接的過程中踩了點坑,會把踩坑跟跳出坑的部份也寫在這篇筆記文裡。


寫 code 前的必要步驟,跳過

在開始寫 code 前有些必要步驟,像是註冊 Auth0、建立 Auth0 App、取得 Client ID、Domain……等,本篇跳過,因為都寫在上一篇中了,這邊就不再重覆寫。

Auth0 Universal Login,做一個自己的會員註冊、登入功能

另外,大部份用 Auth0 接會員登入的 code,本篇也是直接拿上一篇的原始碼來改,可以直接從 GitHub 上下載上一篇完整的原始碼。

https://github.com/letswritetw/letswrite-auth0-login


1 頁面新增登入按鈕

插入登入按鈕的方式,如果對 PHP 很熟,或是 WordPress 架構很熟的朋友,應該會直接改原有的程式碼。

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

但 Augustus 對這二個不太熟 XD~而且以前遇過,從佈景主題編輯器上修改 code 後,一遇到佈景主題有更新,原本加進去的 code 就不見了的狀況。

所以在新增一個登入按鈕的部份,各頁右上角的小按鈕是用 JavaScript 來新增,而各頁右側因為本來小工具就可以加區塊了,就用小工具貼上 HTML 來新增。

這段寫的是用 JS 新增的 code。

確定好按鈕的 HTML,把它寫進變數裡:

const loginHTML = '<div id="letswrite-login"><button class="auth0_login btn btn-letswrite small" id="auth0_login" type="button"><i class="fa fa-user"></i><span>會員 註冊 / 登入</span></button><div class="letswrite-user d-none"><button class="auth0_logout btn btn-letswrite small" id="auth0_logout" type="button">登出</button></div></div>';

CSS 的部份就寫進 WordPress 後台的「編輯 CSS」中。

有了 HTML,接著就是要把按鈕 insert 進指定的區塊中,這邊用的是 insertAdjacentHTML ,這是個好物,自從知道有這 function 後,就不太用 appendChild 了。

insertAdjacentHTML 的用法可以看 MDN 上的說明:Element.insertAdjacentHTML()

完整加上按鈕的 code:

const loginHTMLWrap = document.querySelector('.header-links');
const loginHTML = '<div id="letswrite-login"><button class="auth0_login btn btn-letswrite small" id="auth0_login" type="button"><i class="fa fa-user"></i><span>會員 註冊 / 登入</span></button><div class="letswrite-user d-none"><button class="auth0_logout btn btn-letswrite small" id="auth0_logout" type="button">登出</button></div></div>';
loginHTMLWrap.insertAdjacentHTML('beforeend', loginHTML);

2 登入按鈕的點擊事件

頁面寫進登入按鈕後,下一步就是要寫按鈕的 onclick

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

onclick 時執行 login(),這是 Auth0 的基本用法,上一篇中也有寫到,這邊要額外處理的部份,是一個坑。

在 Auth0 的後台 App 設定中,白名單的部份是不能寫規則運算式的,也就是說不能寫成這樣:

https://letswrite.tw/*

不能用一個 * 符號代表 letswrite.tw 底下的所有頁面,它必須寫一個絕對路徑,否則就一律阻擋。

但,總不能把每一篇文章的網址都手動輸入進後台吧?這有點石器時代的作法。

也不能要求使用者一定只能在首頁做登入吧?這樣子的 UX 有點廢。

Auth0 的說明文件中,是有提供 Pop Up 一個視窗出來,在那個視窗做登入的作法,不過,不能確定 Pop Up 在手機上的應用程度,會不會出現什麼樣子神奇的 bug?(對,就是在說 iOS Safari,根本手機界的 IE)

後來想到的作法,步驟如下:

  1. 先把點擊按鈕的當下,該頁的網址存進 cookies 中。
  2. 如果當下的頁面不在首頁,就把頁面轉到首頁,首頁判斷 cookies 中有沒有值,有的話就執行 login 的 function。
  3. 使用者登入回到首頁後,首頁一樣判斷 cookies 的值存不存在,存在就轉回到第一步中的頁面,並把 cookies 給清掉。

這三步看完,乍看之下沒有問題,但實際上存在著另一個問題,就是如果使用者點了登入按鈕,進到 Auth0 的 Universal Login 的頁面後,沒有想要註冊或登入會員,又按了上一步回到上一頁呢?那因為 cookies 一直有值,頁面就會一直做轉址的動作。

所以在實際寫 code 時,修改後的步驟如下:

  1. 先把點擊按鈕的當下,該頁的網址存進 cookies 中。
  2. 如果當下的頁面不在首頁,就把頁面轉到首頁。首頁判斷 cookies 中有沒有值,有的話就把 cookies 中存進的網址,再存進第二組c ookies中,並執行 login 的 function。
  3. 使用者登入回到首頁後,首頁判斷第二組 cookies 的值存不存在,存在就轉址,並把二組 cookies 都給清掉

登出的部份情況一樣,Auth0 也是有限登出後要轉址到的頁面,設白名單也一樣無法用規則運算式,所以也是要把使用者按下「登出」時,當下頁面的網址給存到 cookies 中,再轉址回首頁做登出,登出完回來後,cookies 中有值就執行轉址回到原頁,並把 cookies 給刪掉。

存、取、刪 cookies 的部份,因為懶,直接用了一個套件:JavaScript Cookie

按下登入、登出後的程式碼:


3 使用者登入後,抓使用者資訊並呈現在頁面上

Auth0 登入後,可以直接用 auth0.getUser() 來取得登入者的資訊。

這邊也踩到了一個坑,從上一篇開始,用 Auth0 Universal Login 的方式,都是引用它們的 auth0-spa-js

用這個 SDK 來登入會有一個問題,因為這是給 SPA(Single-page application)這種一頁式網站來使用,而 WordPress 並不是單頁的,因此在執行 auth0.isAuthenticated() 來判斷使用者是否登入時,除了使用者有確實進到 Universal Login 的頁面做登入的那一次會回傳 true,其它時候都會回傳 false,並且無法透過 auth0.getUser() 來取得使用者資訊。

而且當使用者在 WordPress 上點選任何一篇文章,整個頁面會重新載入,就代表使用者只要進到別篇文章, auth0.isAuthenticated() 永遠都會回傳 false,然後就抓不到使用者登入的資訊。

後來再查了一下官方的說明文件〈Auth0 Single Page App SDK〉,裡面有提供了另一種取得使用者登入資訊的方試,就是拿 access_token 去取。

使用者從 Universal Login 頁面登入回來後,執行 auth0.getTokenSilently() 就可以取得 access_token。那我們要做的就是把這組 token 存下來,當使用者進到別頁後,用這組 token 去取得資訊回來就行了。

那當然,前端能想到的,其實也就是存進 cookies 裡。是說把東西存到 cookies 總覺得有點不安全,但 Auth0 產生的 access_token 會是一組亂數,而且可以自己在後台設定 token 的有效期間,基本上要猜出別的使用者的 token 很難,如果遇到可以破解 token 的高手高手高高手,那……即便不是存在 cookies 裡大概也擋不住了。

這邊 Augustus 提供用 access_token 取得使用者資訊的 code:

fetch 的 URL 記得替換成 Auth0 APP 中提供的 Domain。


放置完成的 JavaScript 檔

JS 檔完成後,最後就是要放進頁面裡。

原本一開始 Augustus 是直接把 script src 寫在小工具的自訂 HTML 裡,後來發現應該是 WordPress 吐出來的小工具位置不對,一直無法執行 JS 檔裡的 function,最後決定放在 GTM中,才成功執行。

Summary
用 Auth0 在 WordPress 上做會員註冊、登入功能
Article Name
用 Auth0 在 WordPress 上做會員註冊、登入功能
Description
本篇大綱:自己的會員功能自己寫。寫 code 前的必要步驟,跳過。1 頁面新增登入按鈕。2 登入按鈕的點擊事件。3 使用者登入後,抓使用者資訊並呈現在頁面上。放置完成的 JavaScript 檔。
Augustus
Let's Write
Let's Write
https://letswrite.tw/wp-content/uploads/2020/08/logo_512.jpg

隨選筆記文

Firebase Google

Firebase Authentication 第三方登入 – GitHub

API

用 Performance API 檢測檔案讀取時間

Vue

用 VuePress 製作說明文件頁面 – 3:導覽列

Front-End

OSM + Leaflet 學習筆記1:建地圖、marker、事件、換圖層

Front-End

從使用者輸入網址,到瀏覽器呈現出來,經過了哪些過程?

PWA

PWA 學習筆記-1:Cache、Workbox 基本使用

Bot Slack

Slack 通知功能 純靜態

Firebase Google

Firebase Cloud Functions 基本使用筆記

Google Others

Youtube Iframe API 常用功能

Front-End

滿版圖片背景、影音背景

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

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

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

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

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

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

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

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

訂閱
通知
guest
0 Comments
Inline Feedbacks
看所有留言