小程序模板網(wǎng)

微信小程序登錄(包括獲取不到unionid的情況)

發(fā)布時(shí)間:2021-05-31 11:47 所屬欄目:小程序開發(fā)教程

我們一般都是先獲取到微信的 unionid,然后再通過 unionid 去登錄自己的網(wǎng)站,就可以關(guān)聯(lián)到用戶在自己網(wǎng)站上的 user_id,但是在小程序登錄中,有時(shí)候可以獲取到 unionid,有時(shí)候獲取不到,在獲取不到 unionid 的情況下,用戶無法正常登錄網(wǎng)站。

UnionID機(jī)制說明: 

  如果開發(fā)者擁有多個(gè)移動(dòng)應(yīng)用、網(wǎng)站應(yīng)用、和公眾帳號(hào)(包括小程序),可通過 unionid 來區(qū)分用戶的唯一性,因?yàn)橹灰峭粋€(gè)微信開放平臺(tái)帳號(hào)下的移動(dòng)應(yīng)用、網(wǎng)站應(yīng)用和公眾帳號(hào)(包括小程序),用戶的 unionid 是唯一的。換句話說,同一用戶,對(duì)同一個(gè)微信開放平臺(tái)下的不同應(yīng)用,unionid 是相同的。

  同一個(gè)微信開放平臺(tái)下的相同主體的 App、公眾號(hào)、小程序,如果用戶已經(jīng)關(guān)注公眾號(hào),或者曾經(jīng)登錄過App或公眾號(hào),則用戶打開小程序時(shí),開發(fā)者可以直接通過 

 獲取到該用戶UnionID,無須用戶再次授權(quán)。(解讀:用戶如果沒有登錄過app,也沒有登錄過公眾號(hào),也沒有關(guān)注過公眾號(hào)的情況下,小程序中通過 是獲取不到 unionid的)

  簡而言之,微信針對(duì)不同的用戶在不同的應(yīng)用下都有唯一的一個(gè) openId, 但是要想確定用戶是不是同一個(gè)用戶,就需要靠 unionid 來區(qū)分。

  通常自己的后臺(tái)都會(huì)有自己的一個(gè)用戶表,每個(gè)用戶有不同的 userid。也就是說同一個(gè)用戶在同一個(gè)微信開放平臺(tái)下的相同主體的應(yīng)用對(duì)應(yīng)著相同的 userid, unionid 以及不同的 openid。所以在用戶登錄進(jìn)來的時(shí)候,我們只能靠微信返回給我們的 unionid 去判斷是不是同一個(gè)用戶,再去關(guān)聯(lián)我們的用戶表,拿到對(duì)應(yīng)的 user_id。

一般情況下(即在登錄小程序之前,已經(jīng)關(guān)注過公眾號(hào)或已經(jīng)登錄過公眾號(hào)或已經(jīng)使用微信登錄的方式登錄過app),用戶通過以下兩步就正常成功登錄網(wǎng)站。

1. 獲取code(登錄憑證,用來換取openid及session_key等)
    ({
      success: function(res){
         if(){
             ();
          }else{
          ('獲取用戶登錄態(tài)失??!'+);
      }
    }
  })

2. 獲取用戶信息(利用返回的code獲取用戶的信息)
  getNeededUserInfo: function(code){
    ({
      url: '',
      method: 'POST',
      data: {
        code: code // 后端通過這個(gè)code去調(diào)用微信的接口(https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code),傳入?yún)?shù)code、appid、appsecret后獲取到微信返回的unionid、openid及session_key等。(然后后端可以直接利用微信返回的信息去關(guān)聯(lián)用戶在自己網(wǎng)站的user_id)      },
      success: function(res){
        // 可以返回前端需要的用戶信息(包括unionid、openid、user_id等)      }
    })
  }

二般情況下(即在登錄小程序之前,既沒有關(guān)注過公眾號(hào),也沒有登錄過公眾號(hào),更沒有使用微信登錄的方式登錄過app),通過 的到的 code 換不回 unionid 及 openid 等信息。

解決思路:通過帶登錄態(tài)的 

 獲取到用戶的加密數(shù)據(jù) encryptedData 和加密算法的初始向量iv,然后將 encryptdata、iv 以及 code傳給后端,后端再去通過接收到的encryptedData、iv以、code 以及之前的 session_key 解密出用戶的 openid、unionid 等。加密數(shù)據(jù)解密算法

以下是具體實(shí)現(xiàn)步驟:

1. 獲取code(登錄憑證,用來換取openid及session_key等)
  ({
    success:  function(res){
      if(){
        ();
      }else{
        ('獲取用戶登錄態(tài)失??!'+);
      }
    }
  })

2. 獲取加密數(shù)據(jù)和加密算法初始向量
舊版本基礎(chǔ)庫調(diào)取()可以直接獲取到微信返回的encryptdata等完整數(shù)據(jù),基礎(chǔ)庫更新之后,需要增加withCredentials屬性,并將屬性值設(shè)置為true時(shí)才可以獲取到除用戶基本信息之外的encryptedData以及iv等數(shù)據(jù)。
需要注意的是:當(dāng)withCredentials值為true時(shí),要求此前有調(diào)用過且登錄態(tài)尚未過期。
  getEncData:  function(){
    ({
      withCredentials: true,
      success: function(res){
        ( code,  res.encryptedData,  res.encryptedData );
      }
    })
  }

3. 獲取用戶信息(利用返回的code獲取用戶的信息)
  getNeededUserInfo:  function(code, enc, iv){
    ({
      url: '',
      method: 'POST',
      data: {
        code: code,
        encryptedData: enc,
        iv: iv
      },
      success: function(res){
        // 可以返回前端需要的用戶信息(包括unionid、openid、user_id等)      }
    })
  }

實(shí)際項(xiàng)目中需要將以上兩種情況整合以后使用。

思路有兩種:

  第一種:( 前端判斷是否有 unionid )在向后端上傳 code 并且后端返回?cái)?shù)據(jù)以后,前端判斷返回值中是否有 unionid 或者 unionid 是否為 null,null 的情況下去調(diào)用帶有用戶登錄態(tài)的(),然后再將微信返回的  encryptedData 和 iv 返回給后端,后端解密出相應(yīng)的信息后再返回給前端;

  第二種:( 后端判斷是否有 unionid )前端在調(diào)用 () 時(shí)候帶著登錄態(tài),然后不管后臺(tái)能不能拿到 unionid,都把 encryptedData 和 iv 返回給后端,后端在拿到前端 code 之后去請(qǐng)求微信的接口拿 unionid,如果返回的 unionid 為空,再拿前端傳的 encryptedData、iv以及之前的 session_key 解密出 unionid。


易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開源 碼云倉庫:starfork
本文地址:http://22321a.com/wxmini/doc/course/25859.html 復(fù)制鏈接 如需定制請(qǐng)聯(lián)系易優(yōu)客服咨詢:800182392 點(diǎn)擊咨詢
QQ在線咨詢