微信小程序登陆(包括获取不到unionid的状况)

  咱们通常都是先获取到微信的 unionid,而后再经过 unionid 去登陆本身的网站,就能够关联到用户在本身网站上的 user_id,可是在小程序登陆中,有时候能够获取到 unionid,有时候获取不到,在获取不到 unionid 的状况下,用户没法正常登陆网站。
 
UnionID机制说明:  
  若是开发者拥有多个移动应用、网站应用、和公众账号(包括小程序),可经过 unionid 来区分用户的惟一性,由于只要是同一个微信开放平台账号下的移动应用、网站应用和公众账号(包括小程序),用户的 unionid 是惟一的。换句话说,同一用户,对同一个微信开放平台下的不一样应用,unionid 是相同的。
  同一个微信开放平台下的相同主体的 App、公众号、小程序,若是用户已经关注公众号,或者曾经登陆过App或公众号,则用户打开小程序时,开发者能够直接经过  wx.login 获取到该用户UnionID,无须用户再次受权。(解读:用户若是没有登陆过app,也没有登陆过公众号,也没有关注过公众号的状况下,小程序中经过 wx.login 是获取不到 unionid的)
 
  简而言之,微信针对不一样的用户在不一样的应用下都有惟一的一个 openId, 可是要想肯定用户是否是同一个用户,就须要靠 unionid 来区分。
  一般本身的后台都会有本身的一个用户表,每一个用户有不一样的 userid。也就是说同一个用户在同一个微信开放平台下的相同主体的应用对应着相同的 userid, unionid 以及不一样的 openid。因此在用户登陆进来的时候,咱们只能靠微信返回给咱们的 unionid 去判断是否是同一个用户,再去关联咱们的用户表,拿到对应的 user_id。
 
通常状况下(即在登陆小程序以前,已经关注过公众号或已经登陆过公众号或已经使用微信登陆的方式登陆过app),用户经过如下两步就正常成功登陆网站。
 1 1. 获取code(登陆凭证,用来换取openid及session_key等)
 2     wx.login({
 3       success: function(res){
 4          if(res.code){
 5              that.getNeededUserInfo(res.code);
 6           }else{
 7           console.log('获取用户登陆态失败!'+res.errMsg);
 8       }
 9     }
10   })
11 
12 2. 获取用户信息(利用wx.login返回的code获取用户的信息)
13   getNeededUserInfo: function(code){
14     wx.request({
15       url: 'https://my.com/login',
16       method: 'POST',
17       data: {
18         code: code // 后端经过这个code去调用微信的接口(https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code),传入参数code、appid、appsecret后获取到微信返回的unionid、openid及session_key等。(而后后端能够直接利用微信返回的信息去关联用户在本身网站的user_id)
19       },
20       success: function(res){
21         // 能够返回前端须要的用户信息(包括unionid、openid、user_id等)
22       }
23     })
24   }
 
二般状况下(即在登陆小程序以前,既没有关注过公众号,也没有登陆过公众号,更没有使用微信登陆的方式登陆过app),经过 wx.login 的到的 code 换不回 unionid 及 openid 等信息。
解决思路:经过带登陆态的  wx.getUserInfo 获取到用户的加密数据 encryptedData 和加密算法的初始向量iv,而后将 encryptdata、iv 以及 code传给后端,后端再去经过接收到的encryptedData、iv以、code 以及以前的 session_key 解密出用户的 openid、unionid 等。 加密数据解密算法
如下是具体实现步骤:
1. 获取code(登陆凭证,用来换取openid及session_key等)
  wx.login({
    success:  function(res){
      if(res.code){
        that.getNeededUserInfo(res.code);
      }else{
        console.log('获取用户登陆态失败!'+res.errMsg);
      }
    }
  })

2. 获取加密数据和加密算法初始向量
旧版本基础库调取wx.getUserInfo()能够直接获取到微信返回的encryptdata等完整数据,基础库更新以后,须要增长withCredentials属性,并将属性值设置为true时才能够获取到除用户基本信息以外的encryptedData以及iv等数据。
须要注意的是:当withCredentials值为true时,要求此前有调用过wx.login且登陆态还没有过时。
  getEncData:  function(){
    wx.getUserInfo({
      withCredentials: true,
      success: function(res){
        that.getNeededUserInfo( code,  res.encryptedData,  res.encryptedData );
      }
    })
  }

3. 获取用户信息(利用wx.login返回的code获取用户的信息)
  getNeededUserInfo:  function(code, enc, iv){
    wx.request({
      url: 'https://my.com/login',
      method: 'POST',
      data: {
        code: code,
        encryptedData: enc,
        iv: iv
      },
      success: function(res){
        // 能够返回前端须要的用户信息(包括unionid、openid、user_id等)
      }
    })
  }

 

实际项目中须要将以上两种状况整合之后使用。
 
思路有两种:
 
  第一种:( 前端判断是否有 unionid )在向后端上传 code 而且后端返回数据之后,前端判断返回值中是否有 unionid 或者 unionid 是否为 null,null 的状况下去调用带有用户登陆态的wx.getUserInfo(),而后再将微信返回的  encryptedData 和 iv 返回给后端,后端解密出相应的信息后再返回给前端;
 
  第二种:( 后端判断是否有 unionid )前端在调用 wx.getUserInfo() 时候带着登陆态,而后无论后台能不能拿到 unionid,都把 encryptedData 和 iv 返回给后端,后端在拿到前端 code 以后去请求微信的接口拿 unionid,若是返回的 unionid 为空,再拿前端传的 encryptedData、iv以及以前的 session_key 解密出 unionid。
相关文章
相关标签/搜索