三週學會小程式(五):登入的原理和實現
登入原理
前面我們耗費在環境搭建上面已經很多時間,這一講開始真正的和小程式功能對接。
登入便是小程式的開始,小程式可以方便的使用微信登入,獲取使用者的個人資訊,這樣我們就能保留使用者的資訊和記錄使用者的操作。我們直接通過一張圖進入正題。如圖是小程式官方給出的登入過程:
ofollow,noindex" target="_blank">三週學會小程式第三講:服務端搭建和免費部署 》要搭建伺服器了。
2,session
key。微信為登入使用者設定的登入session,使用者校驗登入態和下文中我們用於校驗使用者資訊的正確性。
文件地址
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
因為我們不僅僅需要有登入態,還需要獲取使用者資訊儲存到伺服器端 所以我們需要獲取使用者資訊,目前我們獲取使用者資訊需要在小程式端使用 button
元件,並將 open-type
指定為 getUserInfo
型別,點選 button
的時候通過 bindgetuserinfo
屬性 繫結的 callback
接收使用者資訊。通過上述方式我們可以獲取到 rawData
和 signature
, rawData
是使用者資訊
因為
signature=sha1(rawData+session_key)
,
所以我們把這兩個屬性直接傳遞到伺服器端,不僅獲取到了使用者資訊,用於儲存到伺服器端,還能校驗請求資料的真實性。
文件地址
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html
所以這樣以後,小編對流程圖進行了優化,這樣可以減少一次服務端的請求,提高響應速度。

1, 簡單解釋一下,首先在小程式端通過呼叫 wx.login
和 getUserInfo
獲取code 和 使用者資訊,一起通過 wx.request
傳送給開發者伺服器端,這樣便減少一些請求。
2,呼叫 jscode2session
介面到微信介面服務獲取 session_key
和 openId
,直接對使用者資訊進行 SHA1
校驗,校驗成功以後建立自定義登入態,返回自定義登入態到小程式。
3,自定義登入態是什麼呢?做過web的朋友都知道 session 和 cookies 可以組合做登入態,我們這裡也是模擬這種設計,只是我們會把session存到資料庫中,自定義生成 cookies(token) 傳遞給小程式端,儲存到 storage 裡面。因為本講內容較多,所以把資料庫儲存放到了下一講。
4, storage 類似於瀏覽器的 localStorage,使用者小程式端方便的儲存一些基礎資料。
小程式端邏輯實現
現在我們已經理解了怎麼做登入驗證,那接下來我們開始編寫客戶端程式碼。 首先我們需要在 onLoad
方法裡面呼叫 wx.login()
方法, onLoad
方法在頁面載入的是就會呼叫,當頁面載入的時候我們就把 code
存入 data
裡面,以便後面呼叫服務端介面的時候使用。因為每次呼叫 wx.login
對應的 session_key
就會變,所以必須保證 wx.login
的呼叫 在獲取使用者資訊之前。這時候我們每次重新整理頁面都會在控制檯看到如下輸出(我這裡使用的是 Command + S 每次會重新編譯小程式)
然後我們需要在 question/index.wxml
檔案中的按鈕上面新增 open-type
和 bindgetuserinfo
,如下
接下來在 question/index.js
裡面新增 getUserInfo
方法用於接收點選按鈕獲取使用者資訊的回撥,回撥方法裡面的 userInfo
就是我們想要的使用者資訊。我們再模擬器裡面點選按鈕,在控制檯裡面檢視具體的資訊,具體模擬器和控制檯怎麼用,我們在《 客戶端程式碼準備和基礎功能講解 》中已經有講解。
大家應該都知道 JSON
這種資料傳輸格式,我們下面就使用 wx.request
傳送使用者資訊和 code
到伺服器端, wx.request
對於初學者你們可以理解為 ajax
。按照小編的介面定義,我只要傳送 signature
, rawData
和 code
到伺服器端,然後接收資料。所以我的實現如下。
wx.login
成功以後
url
就是請求的地址,
config.serverHost
是我封裝的常量,以便後面修改地址。
method
是請求型別。
data
是請求的
JSON
請求體。
dataType
是定義的請求型別。
success
和
fail
分別是成功和失敗的回撥,我們會根據返回的
response
做相應的處理。wx.request 會把我返回的內容再包裹一個
data
,所以如上內容登入成功和失敗我實際返回的
JSON
如下。
wx.showToast
是提示框,所以當成功以後提示成功,失敗以後把message獲取到提示給使用者。
最後程式碼中你會看到
和
是為了優化一下體驗,當點選登入的時候提示登入中,等待服務端返回資料的時候消失,到此本節小程式部分已經結束。
小程式原始碼地址
https://github.com/codedrinker/jiuask
本講 Tag V5
服務端邏輯實現
上面客戶端已經完成,開始開發服務端。 首先我們需要定義一個 API
入口 Controller
,用於定義 api/login
介面接收小程式發過來的請求。如下:
根據如上程式碼,我們找一些關鍵點講解一下
1,RestController,定義當前 Controller 為 Restful,最簡單的理解就是 @RestController = @ResponseBody + @Controller
2,@Slf4j,Lombok註解,需要在 Idea 外掛中安裝 Lombok,這樣在需要使用日誌的時候,直接使用 log.*()就可以了。
3,@RequestBody LoginDTO loginDTO,會把傳遞過來的 JSON 物件自動序列化成物件。
4,ErrorCodeException 自定義 RuntimeException,根據業務的異常友好的提示到小程式端,具體使用interface和enum實現,原始碼可以參考
com.codedrinker.error
包下面的類。
對於返回物件的統一封裝,便於小程式端接收和處理。
status 是狀態碼,如果不是200,都是異常。
data 是資料,可以是多種型別。
message 返回的錯誤資訊。
@Data 是lombok 的註解,可以自動生成 set get 方法,省去了自己編寫 set get 的麻煩。
下面是對呼叫微信的 API 進行封裝
簡單粗暴的講解一下 Adapter 裡面的關鍵點。
1,@Value("${wechat.appid}") 是 Spring 的自動註解,直接讀取 application-*.yml 裡面的配置賦值給appid變數。這時候我們的
application-production.yml
裡面的配置如下。
appid和secret是在小程式控制臺->開發設定->開發者ID裡面獲取,為了安全,我們不能把這些資訊直接提交到程式碼裡面,所以我選擇了把它們配置到 Heroku
的環境變數裡面,在部署的時候會自動的替換掉 application-production.yml
裡面的 ${WECHAT_APPID}
佔位符,然後通過 @Value
賦值到 @Service
裡面的變數 appid
。具體配置方式如下,還需要先進入 Heroku 的控制檯,然後點選Settings 進行配置,記住左邊是 application-production.yml
裡面的佔位符,右邊是你小程式的 id 和 secret。
2,OkHttpClient,是使用的 OKHttp,小編覺得這個用起來比 Apache 的 HttpClient 要簡單,程式碼就不需要講解了,繼續要因為一個 pom.xml
檔案。
3,JSON.parseObject 直接解析String到物件。
4,throw new ErrorCodeException(CommonErrorCode.OBTAIN OPENID ERROR);
直接返回業務的ErrorCode,
對了,忘記說最重要的一個問題,這次改動需要新增4個pom.xml
已經在原文中添加註釋。
服務端原始碼地址
https://github.com/codedrinker/jiuask-server
本講 Tag V5
我是浪漫的分割線
問答
如果您對本系列文章有興趣,歡迎置頂本訂閱號,第一時間獲取更新。
如果有任何問題,歡迎留言,小編很熱衷和大家一起討論技術問題。
另外小編建立了一個技術交流群,請新增小編微信,切記備註“小程式”,小編拉你進去。【只討論技術,非誠勿擾】
最好的讚賞是關注和分享