1. 程式人生 > >單頁面應用在微信服務號下的登錄流程

單頁面應用在微信服務號下的登錄流程

感知 完成 cookie 它的 們的 方式 留下 sdk 思路

最近我們的小程序涉及到虛擬支付的問題,在ios端的支付被封掉了??,所以有了在服務號上搞一套H5版的小程序的需求。由於我們小程序是mpvue寫的,為了盡量復用之前的樣式和邏輯,選擇了前後端分離的模式,於是一段新的踩坑之旅開始了。放下wx的jssdk暫且不表,今天來說說登錄時遇到的坑。

服務號的登錄流程

以前搞過服務號的同學對於它的登錄流程應該不陌生,就是當後端檢測到當前用戶沒有授權時,將會重定向到微信的授權頁面,當用戶點擊這個授權的button時,微信會根據Url查詢字符串中的重定向URL,重新回到我們的頁面。

下面3幅圖展示了整個過程:

  1. 當我們的服務器發現用戶沒有授權,返回302狀態碼,以及微信的授權頁面location

    技術分享圖片

  2. 用戶在該頁面點擊確認登錄

    技術分享圖片

  3. 微信服務器根據location裏的redirectURL,返回301code,重定向回來

    技術分享圖片

上面三步,經歷了兩次重定向,第一次從自己的服務器重定向到微信的服務器,微信展示授權頁面。第二次重定向是當用戶點擊之後,微信會帶一個code重定向回來,當服務器拿到這個code之後,經歷一波獲取openId的操作之後,生成一個session,這樣用戶以後訪問時就不需要再次登錄。

這樣的模式在傳統的前後端不分離,基於模板的情況下,是沒有問題的,因為沒有json的返回,後端進行邏輯處理後,渲染出html。但是在單頁面的情況下,如果思路跑偏會出現一堆問題。

單頁面遇到的問題

上面說的思路跑偏是什麽意思呢?就是當用戶進來時,先將單頁面的index.html

發給瀏覽器。當瀏覽器執行開始js腳本(app.js)時,就會向服務器發送請求。

此時如果是一個新用戶在訪問,由於沒有登錄,服務器會返回一個302的重定向狀態碼,然而這次請求是通過ajax發起的。瀏覽器不會自動重定向到授權頁面,導致請求失敗。

此時你會想,瀏覽器不會重定向,我可以當請求失敗時通過設置window.location自己重定向到微信授權頁面,這樣解決了第一步的重定向問題,然後當用戶點擊確定登錄時,馬上又面臨第二個重定向的問題--重定向到哪裏。

由於微信重定向的url是帶著code返回的,重定向的Url肯定不能是一個靜態頁面的Url,必須是一個api,假設還是login。後端在請求中拿到code之後,生成一個新的session,再將原先的html再次返回給瀏覽器,並帶上set-cookie

字段,此後瀏覽器會帶著cookie請求,登錄至此完成。

這樣做ok,當時卻留下一個很恐怖的URL:https://example.com/login?code=001QLbSQ0Ujc162Sp5UQ0IG6SQ0QLbSD,此後前端路由開始work,就在前面的基礎上加上一個#號,如果你的業務還涉及支付,那就完蛋了,因為支付需要配置的url應該是穩定的而code這個查詢參數是動態變的。

解決方案

我畫了一張圖解釋了重新設計的登錄流程:

技術分享圖片

在這個新的流程中,當新用戶第一次發起請求(login)時,不會返html給瀏覽器,只會進行重定向:

  • 如果用戶未登錄,重定向到微信的授權頁,並設置redirect url,使用戶點擊授權後可以重定向回來

  • 新用戶重定向回來之後,login api拿到code,經過生成session操作後,再次重定向到homeurl下

  • 如果是老用戶,直接重定向到homeurl下

  • 此時由於訪問home的用戶都是已登錄狀態,api統一返回index.html,所以最終用戶看到的是https://example.com/home下的頁面,後面的單頁面路由會在這個url下展開。(雖然對服務號用戶來說可能沒什麽區別)

總結一下這麽做的好處:

  1. 少傳輸一次html頁面,第一種方式一開始就給未登錄的用戶傳html是沒用的

  2. 美觀的url(用戶感知不到)

  3. 前端無需手動重定向,後端將顯示頁面和登錄邏輯放到兩個api中,邏輯更清晰

總結

了解到3xx狀態碼的博大精深,盡管對普通用戶感知不深,沒有2xx受群眾歡迎,也沒有404,500知名度高,屬於默默無聞型的。但是在互聯網世界裏卻扮演著重要的角色。

單頁面應用在微信服務號下的登錄流程