无码人妻精一区二区三区,eeuss影院www在线观看,无码精品久久久久久人妻中字,日韩av高清在线看片

推薦新聞
從session原理出發(fā)解決微信小程序的登陸問題
發(fā)布者:深藍(lán)互聯(lián)
發(fā)布時(shí)間:2019-12-28
點(diǎn)擊:次

原理知識(shí)準(zhǔn)備

   對(duì)于已經(jīng)熟悉了session原理的同學(xué)來說,我們都清楚:在瀏覽器端我們會(huì)存儲(chǔ)一個(gè)sessionId,用它來作為憑證,在服務(wù)器端得到有關(guān)本次瀏覽器與服務(wù)器會(huì)話的所有信息,這些信息是儲(chǔ)存在服務(wù)器端的存儲(chǔ)空間中的,它完全可以用來判斷一個(gè)瀏覽器端的登錄狀態(tài),因?yàn)樗怯煞?wù)器端來掌控的,是安全的。

  那么瀏覽器端是用什么來存儲(chǔ)這個(gè)sessionId? 并且瀏覽器又是如何將sessionId傳回給服務(wù)器的呢?

  大體上是有兩種方法的:

    1、使用瀏覽器端實(shí)現(xiàn)的cookie功能,每次瀏覽器都會(huì)將服務(wù)器傳過來的cookie內(nèi)容按鍵值對(duì)的方式放到瀏覽器的緩存中,然后下次請(qǐng)求同一個(gè)服務(wù)器時(shí)又會(huì)將cookie內(nèi)容取出來送回服務(wù)器,當(dāng)然其中就有存儲(chǔ)在cookie中的sessionId。

    2、使用URL重寫的方法,URL地址重寫是對(duì)客戶端不支持Cookie的解決方案。URL地址重寫的原理是將該用戶Session的id信息重寫 到URL地址中。服務(wù)器能夠解析重寫后的URL獲取Session的id。這樣即使客戶端不支持Cookie,也可以使用Session來記錄用戶狀態(tài)。

 

 

    

  不到迫不得已的地步,我是不會(huì)考慮第二種,也就是使用URL重寫的方法的。

 

  其實(shí),實(shí)際的應(yīng)用場(chǎng)景無非就是以下兩種,我們用病人看病的例子來理一理:

 

  第一種,醫(yī)生給病人看病,一天有幾百個(gè)病人,不可能把所有的病人的病情都記得清清楚楚,所以就需要一個(gè)病歷本,病人下次來看病的時(shí)候醫(yī)生就可以根據(jù)病人的病歷本上記錄的信息來得到病人的病情狀況。(這種情況對(duì)應(yīng)的就是瀏覽器端只使用cookie與服務(wù)器進(jìn)行交互的情況)

 

  第二種,有一些特殊的病人,他們是毒癮患者,正在接受戒毒的輔助治療,每個(gè)月需要到醫(yī)院領(lǐng)取少量的類似毒品的藥物來逐步減少毒品攝入量;醫(yī)院也給他一個(gè)病歷本,但是由于使用藥物的特殊性,為了防止某些不法分子偽造病歷本去領(lǐng)取違禁藥物,于是就給每個(gè)病歷本上使用GUID算法生成了一個(gè)獨(dú)一無二的病歷號(hào),在醫(yī)生這里也有一個(gè)本子,上面記錄了所有特殊病人的病歷號(hào),下次病人來拿違禁藥物的時(shí)候,醫(yī)生需要對(duì)照病人的病歷號(hào)來查詢是否存在這個(gè)病人和他需要領(lǐng)取藥品的具體量。這樣,就可以防止非法人員冒充和病人惡意更改藥品領(lǐng)取量的情況發(fā)生。(這種情況對(duì)應(yīng)的就是通過sessionId來查詢出本次瀏覽器與服務(wù)器的會(huì)話信息的情況,病歷本上的病歷號(hào)就相當(dāng)于sessionId)

 

   上面寫了這么多關(guān)于session的原理內(nèi)容就是為了下面引出正題做準(zhǔn)備的,所以到這里還不明白session原理的同學(xué)可以繞道去找一些關(guān)于session的文章研究研究,再回來接著往下看。

  推薦一篇大神的關(guān)于session原理的文章:

  https://www.cnblogs.com/linguoguo/p/5106618.html

 相關(guān)閱讀:品牌負(fù)面輿情監(jiān)控公關(guān)管理

問題提出

 

  下面展開正題,問題是這樣的:

  在開發(fā)微信小程序的過程中需要實(shí)現(xiàn)一個(gè)小程序登陸的功能,由于小程序中與服務(wù)器的交互大部分使用的都是HTTP通信,所以完全可以仿照之前開發(fā)B/S的那一套登陸體系,利用上面提到的sessionId的方式在服務(wù)器端進(jìn)行登陸態(tài)的存儲(chǔ),進(jìn)行是否登錄的判斷。相對(duì)于以前的 服務(wù)器/瀏覽器 的開發(fā)模式,服務(wù)器/微信小程序 的開發(fā)模式有一個(gè)初級(jí)開發(fā)者需要注意的點(diǎn),就是:微信小程序是不會(huì)將HTTP報(bào)文頭中的COOKIE信息存入緩存中的,自然也就不會(huì)將COOKIE的內(nèi)容傳回給服務(wù)器端,簡(jiǎn)單的說就是 微信小程序端沒有幫你實(shí)現(xiàn)cookie機(jī)制

  

   所以,如果你想當(dāng)然的就認(rèn)為微信小程序已經(jīng)幫你在背后實(shí)現(xiàn)了cookie機(jī)制,那么你就會(huì)像我一樣,踩入了一個(gè)大坑。
 
  下面是我的踩坑歷程,咱從坑中領(lǐng)悟: 
 
  
服務(wù)器端的一段程序(.net MVC 的 Action方法程序)
  
復(fù)制代碼
        public ActionResult SessionTest()
        {
            Session["TestValue"] = 1;

            return Json(new { message = "this is a test response" });
        }    
復(fù)制代碼

  

使用微信小程序的原生request方法寫的請(qǐng)求程序

復(fù)制代碼
 sendRequest:function(){

    wx.request({

        url:'http://localhost:51112/Test/SessionTest',
        method:'POST',
        success:function(res){

          console.log("進(jìn)行了一次請(qǐng)求");

        },
        fail:function(){

          console.log("請(qǐng)求失敗");

        }
    });

  }
復(fù)制代碼

 

   過程就是用小程序的這段代碼運(yùn)行,去請(qǐng)求服務(wù)器,服務(wù)器執(zhí)行的就是上面展示的那段action方法的代碼。

   總共請(qǐng)求兩次,兩次請(qǐng)求的http報(bào)文頭如下:

  第一次請(qǐng)求:

  

 

 

 ?。ㄕ?qǐng)求報(bào)文頭):

   

 

  (應(yīng)答報(bào)文頭):

 

 

  由于這是微信小程序第一次與服務(wù)器進(jìn)行交互,所以并沒有攜帶任何cookie的內(nèi)容,這是很正常的現(xiàn)象。等到服務(wù)器應(yīng)答瀏覽器時(shí),就給了瀏覽器一個(gè)sessionId,字段名為 ASP.NET_SessionId  值為  saqu0pv20q5jkd1q2dlmxcyg 。到這里我們?nèi)绻J(rèn)為微信小程序已經(jīng)實(shí)現(xiàn)了cookie機(jī)制,那么下一次向同一個(gè)域名進(jìn)行請(qǐng)求的時(shí)候,我們會(huì)在請(qǐng)求報(bào)文頭中看到會(huì)有一個(gè)cookie字段,里面會(huì)有上一次微信小程序從服務(wù)器那里得到的sessionId的值。

  然而。。。

  

 第二次請(qǐng)求:

 

  

 

       (請(qǐng)求報(bào)文頭):

   

 

 ?。☉?yīng)答報(bào)文頭):

    

 

   看到這里你就會(huì)發(fā)現(xiàn)它與你預(yù)想的完全不一樣了。。首先,請(qǐng)求報(bào)文頭中并沒有發(fā)現(xiàn)有上一次服務(wù)器給微信小程序端傳的sessionId;然后,服務(wù)器返回給小程序的報(bào)文頭中的 ASP.NET_SessionId  值變成了 cwugbbt0mmliha0ul4ccx4l2  并非原先的  saqu0pv20q5jkd1q2dlmxcyg 。

   發(fā)生的一切都指向一個(gè)原因,那就是 小程序并沒有實(shí)現(xiàn)cookie的機(jī)制,導(dǎo)致小程序請(qǐng)求服務(wù)器的報(bào)文頭中并沒有攜帶sessionId,服務(wù)器拿不到sessionId,就會(huì)認(rèn)為這是另外一個(gè)還沒有對(duì)服務(wù)器請(qǐng)求過的客戶端,就新生成了一個(gè)sessionId給微信小程序端,所以小程序端就拿到了不同于上次的sessionId。

 

   到現(xiàn)在,所有的現(xiàn)象以及現(xiàn)象背后的原因都解釋通了,那么接下來就是怎么解決問題。

 

解決方法與過程

      其實(shí)解決問題的方法很簡(jiǎn)單,既然微信小程序端沒有實(shí)現(xiàn)cookie機(jī)制,那么就自己實(shí)現(xiàn)cookie機(jī)制唄。

   思路:cookie機(jī)制最簡(jiǎn)單的功能無非就是將服務(wù)器返回的 應(yīng)答報(bào)文中cookie部分找個(gè)地方存起來,以后再向服務(wù)器發(fā)出請(qǐng)求時(shí)就將存儲(chǔ)的cookie內(nèi)容取出,填充到請(qǐng)求報(bào)文頭中。

   存到一個(gè)地方,存到哪呢?有兩個(gè)合適的地方:

    1、微信小程序的緩存。

      2、微信小程序的全局變量中。

   我選擇第二種,將cookie內(nèi)容存到微信小程序的全局變量中去,下面是我自己封裝的一個(gè)自動(dòng)攜帶cookie中的sessionId去請(qǐng)求的請(qǐng)求函數(shù)實(shí)現(xiàn):

 

   在封裝之前,最好先去微信小程序的官網(wǎng)看一下   wx.request 函數(shù)的說明。點(diǎn)這里

 

復(fù)制代碼
//app.js
App({
  
  globalData: {
    cookie: '',      //供小程序存儲(chǔ)cookie數(shù)據(jù)使用
  }
})
復(fù)制代碼
復(fù)制代碼

 
//帶著sessionId進(jìn)行請(qǐng)求,自動(dòng)獲取服務(wù)端返回的sessionId存入全局變量中
function RequestBySessionId(requestParam){

  //三個(gè)默認(rèn)參數(shù)的值
  var method = "GET";
  var dataType = "json";
  var responseType = "text";
  //用戶輸入了參數(shù)就替換,沒輸入就使用默認(rèn)的
  if ("method" in requestParam)
  {
    method = requestParam.method;
  }
  if ("dataType" in requestParam) {
    dataType = requestParam.dataType;
  }
  if ("responseType" in requestParam) {
    responseType = requestParam.responseType;
  }

  var url = requestParam.url;
  var data = requestParam.data;
  var success = requestParam.success;
  var fail = requestParam.fail;
  var complete = requestParam.complete;

  var cookieStr = "";  //請(qǐng)求報(bào)文頭中cookie的字符串

  var Cookie = App.globalData.cookie;  //獲取全局變量中的cookie內(nèi)容
  cookieStr = Cookie;

  var header = {};
  if ("header" in requestParam)
  {
    header = requestParam.header;
    header["Cookie"] = cookieStr;
  }
  else
  {
    header["Cookie"] = cookieStr;
  }

  wx.request({
    url: url,
    method: method,
    responseType: responseType,
    dataType: dataType,
    data: data,
    header: header,    //每次請(qǐng)求帶上sessionId
    success: function(res){

      //先將檢查服務(wù)器返回報(bào)文頭中有無sessionId,有則存到全局變量中
      var cookie = res.header["Set-Cookie"];
      if (undefined != cookie)
      {
        var sessionPos;
        if ((sessionPos = cookie.indexOf("ASP.NET_SessionId=")) != -1) {

          //每次請(qǐng)求成功都將sessionId存入全局變量
          App.globalData.cookie = cookie.substring(sessionPos, 42);
        }
      }
      //執(zhí)行正常的操作
      success(res);
    },
    fail: fail,
    complete: complete,
  });
}
復(fù)制代碼

 

  經(jīng)過了這一波封裝,就等于是有了微信小程序中請(qǐng)求的”神器“了,麻麻再也不用擔(dān)心我把sessionId搞丟了。

  

  下面咱就再一次使用封裝后的函數(shù)來進(jìn)行請(qǐng)求發(fā)送試驗(yàn):

  

   改造后的微信小程序端請(qǐng)求代碼:

 

復(fù)制代碼
  var utils = require('../../utils/util.js'); //引用 util.js 文件
  sendRequest:function(){

    utils.RequestBySessionId({

      url: 'http://localhost:51112/Test/SessionTest',
      method: 'POST',
      success: function (res) {

        console.log("進(jìn)行了一次請(qǐng)求");

      },
      fail: function () {

        console.log("請(qǐng)求失敗");

      }
    });

  }
復(fù)制代碼

 

 

 

  

   同樣的過程:用小程序的這段代碼運(yùn)行,去請(qǐng)求服務(wù)器,服務(wù)器執(zhí)行的就是上面原先展示的那段action方法的代碼。

   總共請(qǐng)求兩次,兩次請(qǐng)求的http報(bào)文頭如下:

  第一次請(qǐng)求:

  

 

 

 ?。ㄕ?qǐng)求報(bào)文頭):

   

 

 

  (應(yīng)答報(bào)文頭):

 

 

 

  看到這次服務(wù)器返回的 ASP.NET_SessionId  值為  dodngz2ahcznp4r3hrmavd1c。

  然后,注意了。。。

  

 第二次請(qǐng)求:

 

  

 

       (請(qǐng)求報(bào)文頭):

   

 

   看到第二次請(qǐng)求報(bào)文頭中的cookie了嗎,里面就是 ASP.NET_SessionId= dodngz2ahcznp4r3hrmavd1c,

   說明了,已經(jīng)成功將sessionId帶上了。。。

 

 ?。☉?yīng)答報(bào)文頭):

    

 

  服務(wù)器返回的報(bào)文中已經(jīng)沒有sessionId了,因?yàn)橐呀?jīng)不需要了。。。

 

關(guān)注深藍(lán)互聯(lián)公眾號(hào)
Copyright ? 2013-2025 深藍(lán)互聯(lián) 版權(quán)所有
友情鏈接: