一開始做註冊頁時,我其實只知道要把表單完成,對後面的會員流程幾乎毫無頭緒。
直到團隊開始討論「登入前和登入後能使用哪些功能」,我才發現,註冊並不是把資料送出去就結束了。
以 PawPal 來說,沒有登入的使用者,仍然可以瀏覽首頁和搜尋醫院。
但只要要建立、查看或管理自己的寵物資料,就必須先註冊並登入。
這也是我當時最容易理解的分界:
未登入
→ 瀏覽首頁
→ 搜尋醫院
登入後
→ 新增寵物
→ 查看與管理自己的寵物資料
→ 進入需要會員身分的頁面
原本我只把登入理解成「有沒有帳號」,後來才發現,它其實會影響整個網站的功能入口、頁面內容和操作流程。
PawPal 當時的做法,是在未登入時隱藏部分會員功能入口,像是新增寵物和查看個人寵物資料。
需要會員身分的頁面,也會受到路由守衛限制。
當時我只覺得這樣最直接,沒有再進一步思考,功能入口被隱藏後,第一次進站的使用者是否還能知道登入後可以做什麼。
這個問題,也是我現在回頭看這段流程時,才重新注意到的。
PawPal 最初的註冊流程是:
填寫註冊表單
→ 建立帳號
→ 註冊成功
→ 導向登入頁
→ 再輸入一次帳號和密碼
→ 完成登入
這個流程本身沒有錯。
使用者可以成功建立帳號,也能接著登入網站。
但我在觀察其他網站時發現,許多服務在註冊完成後,就會直接讓使用者進入登入狀態。
相比之下,PawPal 的使用者才剛輸入過帳號和密碼,完成註冊後卻還要再輸入一次,操作上多了一個重複步驟。
所以我開始思考:
既然使用者才剛完成註冊,能不能直接幫他接著登入?
這次調整不是因為原本的功能壞掉,而是單純想讓整段操作更順。
原本我會把註冊和登入想成差不多的功能。
直到實際處理自動登入流程後,我才發現,它們在程式裡其實是兩段不同的流程。
註冊使用的是:
POST /api/v1/auth/register
送出的資料主要包含:
name
email
password
註冊成功後,後端會建立會員資料,並回傳建立完成的使用者資訊。
但這支註冊 API 不會直接回傳 Token。
真正取得 Token 的地方,是登入 API:
POST /api/v1/auth/login
登入成功後,才會回傳:
token
user
所以「註冊後自動登入」,不是單純把註冊成功後的導頁從 /login 改成 /dashboard。
實際上是註冊完成後,前端再自動執行一次登入流程。
調整後,整段流程變成:
送出註冊表單
→ 呼叫註冊 API
→ 確認帳號建立成功
→ 自動呼叫登入 API
→ 取得 Token 和會員資料
→ 保存登入狀態
→ 導向 Dashboard
在前端程式裡,流程大致是從註冊表單的送出事件開始:
RegisterForm.handleSubmit
→ authStore.register()
→ sessionStore.login(email, password)
→ router.push('/dashboard')
看起來只有幾個步驟,但每一步都有自己的責任。
如果只完成註冊,使用者還沒有 Token。
如果取得 Token,卻沒有保存登入狀態,其他需要會員身分的功能還是無法正常使用。
因此,程式不能只處理最後的導頁,還要先完成 Token、會員資料與登入狀態的保存,才能讓後續會員功能接著使用。
router.push() 只是最後一步以前看到註冊成功後跳頁,我可能只會注意到這一行:
router.push('/dashboard')
實際做過後,我才知道,這只是整段流程的最後一步。
在導頁以前,前端還需要:
PawPal 會把 Token 和會員資料分別保存為:
pawpal_token
pawpal_user
後續呼叫需要會員身分的 API 時,再把 Token 放進 Request Header:
Authorization: Bearer <token>
這樣後端才能確認目前是哪一位使用者。
JWT 更完整的結構與驗證方式,我會留到後面的文章再整理。這一篇先把重點放在註冊、登入和前端狀態之間的關係。
加入自動登入後,流程也多了一個需要注意的情況:
帳號已經註冊成功,但後面的自動登入失敗了怎麼辦?
此時會員帳號其實已經建立完成,失敗的是後續登入流程。
所以程式需要把「註冊失敗」和「註冊成功,但自動登入失敗」視為不同情況處理。
我也替這段自動登入流程補上測試,確認註冊成功後會接著呼叫登入流程;如果自動登入失敗,也不會直接把使用者帶進 Dashboard。
這讓我第一次比較明確地感受到:
流程變得更方便時,通常也代表需要處理更多狀態。
完成後最明顯的差異,就是使用者不需要重新輸入一次帳號和密碼。
技術上只是把原本分開的註冊與登入流程接起來,但對使用者來說,整段操作會順很多。
這次也讓我發現,使用者體驗不一定來自一個很大的功能改版。
有時候只是少掉一次重複輸入、少經過一個頁面,就能讓整段操作自然很多。
以前的我會覺得,只要註冊 API 回傳成功,帳號有建立完成,註冊功能就算做完了。
但從使用者的角度來看,他真正想做的通常不是「完成註冊」本身。
他可能是想新增寵物、查看醫療紀錄,或開始使用其他會員功能。
註冊只是進入這些功能之前,必須經過的一個步驟。
所以註冊成功後要去哪裡、登入狀態有沒有接上、下一個畫面能不能立刻使用,都是會員流程的一部分。
這次從註冊頁開始,我才第一次比較完整地理解:
功能完成,不只是 API 有沒有成功,也要看使用者能不能順利走到下一步。
如果現在重新設計這段會員流程,我不會只檢查註冊 API 有沒有成功。
我會先把整段使用者路徑整理出來:
使用者為什麼註冊
→ 註冊成功後需要什麼狀態
→ 下一個要使用的功能是什麼
→ Token、會員資料和登入狀態要在什麼時候完成
→ 如果自動登入失敗,要怎麼繼續操作
我也會重新思考未登入時的功能入口。
當時 PawPal 對部分會員功能的做法,是未登入時直接不顯示。
如果重新設計,我會考慮保留部分入口,讓使用者點擊後再前往登入頁。
這樣除了限制未登入使用者的操作,也能讓第一次進站的人知道登入後可以使用哪些功能。
不過,這仍然是我現在回頭看的想法,不是 PawPal 當時已經完成的設計。
這次可以先記住幾件事:
router.push() 只是最後一步,而 UX 的改善有時只是拿掉一個重複步驟。以前我會從功能的角度看:
帳號有建立成功,註冊功能就完成了。
現在我會再多問一句:
使用者完成註冊後,能不能順利走到他真正想使用的功能?
這次我才理解,前端不只是把每個功能分別做出來,也要讓它們之間的流程接得起來。
註冊後自動登入,讓使用者可以直接進入會員頁面。
但進入會員頁面後,前端還會遇到下一個問題:
我們已經知道使用者登入了,但要怎麼知道現在登入的是誰?
下一篇會接著整理 PawPal 如何取得目前登入的會員資料,以及前端要怎麼把「已登入」變成畫面上真正能使用的會員資訊。
下一篇:
Day 12|為什麼登入後還要知道「我是誰」?