1. 程式人生 > >青銅選手帶你動手擼一個部落格小程式給自己(可能是第二期)~(大佬請忽略此條)

青銅選手帶你動手擼一個部落格小程式給自己(可能是第二期)~(大佬請忽略此條)

前言

上一篇的的的連結 賴了一個星期了,let us 接著上一篇的搞。

在上一篇裡搞了一下基礎設施建設,這一篇我們...稍微搞那麼一丟丟上層建築。

這一篇裡本菜雞想分享的tip

  • 小程式登陸邏輯與登陸狀態維持的兩種姿勢
  • 傳送評論時的一個投機倒把的小“優化”

小程式微信登陸與前端登陸狀態儲存

小程式登陸

小程式登陸其實是個比較簡單的基本操作,但凡是看過微信開發文件的應該都能懂,不過本菜雞還是想嘗試性的分享一下。

首先先明確一下為啥要用微信登陸,在本菜雞看來在這個專案裡使用微信登陸主要有三個目的

  • 方便使用者 :相比於使用者手動註冊、填寫各種資訊、再手動輸入賬號密碼登陸,利用微信登陸使用者點一下,就可以完成上面的全部操作,註冊、登陸全都由後臺利用微信提供的相關的資訊完成
  • 方便後臺使用者管理
  • 使用微信的相關能力:通過微信登陸,後臺可以獲得唯一標識使用者的openid,而這個openid,是後臺呼叫微信相關敏感介面的必填項(例如:微信支付)

然後,明確一下微信登陸過程中的幾個概念

名稱 獲取方式 特點 用法
code 通過小程式端呼叫wx.login方法 一次性的,每次呼叫wx.login所得到的code均不同 傳遞給後臺,與appid、appsecrect拼接成微信登陸的url
openid 通過訪問微信登陸url(由appid、appsecrect、code拼接而成)得到的返回結果json中取到 1.能唯一的標識出本小程式的使用者 2.屬於敏感資訊應存放在後臺 3.後臺呼叫微信一些高階介面的必填項
appid 微信公眾平臺後臺 每個小程式的唯一標識 屬於敏感資訊應存放在後臺 後臺呼叫微信介面的必須項
appsecrect 微信公眾平臺後臺 屬於敏感資訊應存放在後臺 後臺呼叫敏感微信介面的必須項

然後,結合本次專案的實際情況捋一下微信登陸的流程

  1. 呼叫wx.login方法獲取code,順手呼叫一下wx.getUserInfo獲取一下使用者的基本資訊(頭像,微信名啥的)
  2. 呼叫後端介面,將code與獲取的使用者資訊userInfo(非必需)傳遞給後端。
  3. 後端接收到引數,將code拿出來與存在後端的appid、appsecrect拼接成微信登陸連結
$url='https://api.weixin.qq.com/sns/jscode2session?appid='.$this->appId.'&secret='.$this->appSecret.'&js_code='.$code.'&grant_type=authorization_code';
複製程式碼
  1. 訪問該連結獲得返回結果(json格式的),驗證下是否成功,如果OJBK,就從結果裡掏出openid
 $wxResult=json_decode(curl_get($url),true);
 if(!$wxResult||!array_key_exists('openid',$wxResult)){
      return ResultService::failure('獲取openid不成功');
 }
 $openId=$wxResult['openid'];
複製程式碼

其實獲得到openid微信登陸已經差不多了,剩下就是怎麼用的問題了,下面的步驟是在本次專案的流程,供各位老哥參考

  1. 根據openid查一下資料庫,看看是否是存在,若存在,則說明是老使用者,不用新增使用者,直接用在步驟3中獲取到的由前端傳來的userInfo更新一下後臺的使用者資訊即可(頭像,省份,微信名啥的)。若不存在,則這是個新使用者,把openid與userInfo存到使用者表中
  2. 經過步驟5,庫裡已經有了這個使用者的資料,然後拿使用者資料,按照一定規則,生成個token返回給小程式端,小程式端把token存到localStorage裡,後端將token與使用者資訊以鍵值對的形式存到快取裡,以後小程式請求的時候帶著token來,後端根據token查快取來確定使用者登陸狀態。

至此,本專案中微信登陸的流程搞完了。登陸完的結果就是,後臺新增或更新了使用者資料,小程式端有了token。

小程式登陸狀態保持

本菜雞個人覺得常用的保持登陸狀態的方法有兩種

  • token(個人推薦)
  • session

先說第一種,也是本專案採用的方法,其實在上面的步驟5、6已經把這個方法將清楚了,

  1. 登陸後服務端下發token給小程式端,
  2. 同時服務端自己也存一份,存哪裡就根據實際情況(cache、redis、session啥的都行),然後搞個有效期,過期了就消失得那種。
  3. 小程式每次請求後端介面的時候把token放到header裡
  4. 後端在處理請求前先把token從header裡取出來,拿這個token去查快取,如果有,就說明使用者還在登陸狀態,繼續往後走,如果沒有,則說明使用者離線了,就直接返回一下告訴小程式端需要重新登陸,小程式收到後跳轉到登入頁。

第二種也在做網站使用者登陸的時候是非常常見的操作,在擼網站的時候,使用者登陸後把使用者資訊存到session裡,使用者在請求的時候能夠從session中取到使用者資訊,之所以這樣是因為,瀏覽器請求伺服器,伺服器響應時,會帶一個sessionid回去給瀏覽器,瀏覽器下次請求時候會自動帶著sessionid,伺服器會根據sessionid來到相應的會話裡,所以能取到session中的使用者

BUT在小程式中有所不同,這是因為小程式網路訪問是用的微信封裝的wx.request,而該方法並不會把sessionid存下來,因此,為了能和網站登陸搞成一個邏輯,我們手動存一下sessionid,在下次請求的時候帶著sessionid去即可。

部分程式碼如下

服務端(PHP)

//前面先搞登陸,登陸完了把使用者存到session裡然後
return ResultService::success('',['sessionId'=>session_id()]);

複製程式碼

小程式端

//登陸
dataUtils.userLogin({ code: code, info: JSON.stringify(info) }).then(res => {
        if (res.statusCode == '200') {
          wx.setStorageSync('sessionId', res.data.data.sessionId);
          $Message({
            content: '登陸成功',
            type: 'success'
          });
          this.checkUserLogin();
        }
        else {
          $Message({
            content: '登陸未成功',
            type: 'error'
          });
        }
//請求例子(不同後端header名不一樣,比如php的後端就是 PHPSESSID=你的sessionId)
function userJoinPromise(data,sessionId){
  let url = 'travel/api/userJoin';
  return getServerDataPromise(url, data, { 'Cookie': 'PHPSESSID=' + sessionId });
}
複製程式碼

下班了下班了,先寫到這明天繼續擼