我们一般都是先获取到微信的 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),用户通过以下两步就正常成功登录网站。
. 获取code(登录凭证,用来换取openid及session_key等)
wx.login({
  success: function(res){
  if(res.code){
  that.getNeededUserInfo(res.code);
}else{
      console.log('获取用户登录态失败!'+res.errMsg);
      }
    }
  }) . 获取用户信息(利用wx.login返回的code获取用户的信息)
  getNeededUserInfo: function(code){
    wx.request({
      url: 'https://my.com/login',
      method: 'POST',
      data: {
        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)
      },
      success: function(res){
        // 可以返回前端需要的用户信息(包括unionid、openid、user_id等)
      }
    })
  }
二般情况下(即在登录小程序之前,既没有关注过公众号,也没有登录过公众号,更没有使用微信登录的方式登录过app),通过 wx.login 的到的 code 换不回 unionid 及 openid 等信息。
解决思路:通过带登录态的 wx.getUserInfo 获取到用户的加密数据 encryptedData 和加密算法的初始向量iv,然后将 encryptdata、iv 以及 code传给后端,后端再去通过接收到的encryptedData、iv以、code 以及之前的 session_key 解密出用户的 openid、unionid 等。加密数据解密算法
以下是具体实现步骤:
. 获取code(登录凭证,用来换取openid及session_key等)
  wx.login({
    success: function(res){
      if(res.code){
        that.getNeededUserInfo(res.code);
      }else{
        console.log('获取用户登录态失败!'+res.errMsg);
      }
    }
  }) . 获取加密数据和加密算法初始向量
旧版本基础库调取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 );
      }
    })
  } . 获取用户信息(利用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。
 

微信小程序登录(包括获取不到unionid的情况)的更多相关文章

  1. 微信小程序登录,获取code,获取openid,获取session_key

    微信小程序登录 wx.login(Object object) 调用接口获取登录凭证(code).通过凭证进而换取用户登录态信息,包括用户的唯一标识(openid)及本次登录的会话密钥(session ...

  2. 关于小程序登录时获取openId和unionId走过的坑

    目前的项目是在做小程序这方面的,接触过的人应该都知道,同一个微信开放平台下的相同主体的App.公众号.小程序的unionid是相同的,这样就可以锁定是不是同一个用户.微信针对不同的用户在不同的应用下都 ...

  3. 微信小程序登录对接Django后端实现JWT方式验证登录

    先上效果图 点击授权按钮后可以显示部分资料和头像,点击修改资料可以修改部分资料. 流程 1.使用微信小程序登录和获取用户信息Api接口 2.把Api获取的用户资料和code发送给django后端 3. ...

  4. Flask与微信小程序登录(后端)

    开发微信小程序时,接入小程序的授权登录可以快速实现用户注册登录的步骤,是快速建立用户体系的重要一步.这篇文章将介绍 python + flask + 微信小程序实现用户快速注册登录方案(本文主要进行后 ...

  5. 微信小程序案例:获取微信访问用户的openid

    在微信开发项目中,获取openid是项目常遇的问题,本文通过主要讲解实现在微信小程序中如何获取用户的openid,案例实现非常简单 具体实现方法是通过登录接口获取登录凭证,然后通过request请求微 ...

  6. 微信小程序登录方案

    微信小程序登录方案 登录程序 app.js 调用wx.login获取code 将code作为参数请求自己业务登录接口获取session_key 存储session_key 如果有回调执行回调 App( ...

  7. 基于Shiro,JWT实现微信小程序登录完整例子

    小程序官方流程图如下,官方地址 : https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html ...

  8. 微信小程序登录JAVA后台

    代码地址如下:http://www.demodashi.com/demo/12736.html 登录流程时序登录流程时序 具体的登录说明查看 小程序官方API 项目的结构图: springboot项目 ...

  9. 全栈项目|小书架|微信小程序-登录及token鉴权

    小程序登录 之前也写过微信小程序登录的相关文章: 微信小程序~新版授权用户登录例子 微信小程序-携带Token无感知登录的网络请求方案 微信小程序开通云开发并利用云函数获取Openid 也可以通过官方 ...

  10. Taro -- 微信小程序登录

    Taro微信小程序登录 1.调用Taro.login()获取登录凭证code: 2.调用Taro.request()将code传到服务器: 3.服务器端调用微信登录校验接口(appid+appsecr ...

随机推荐

  1. 12、类成员访问修饰符public/private/producted/readonly

    1.private 类的私有成员 private 类的私有成员,只能在内部访问,在外部访问不到,无法被继承,我们可以将不需要被外部修改的定义为私有的 私有成员,只能在内部访问,在外部访问不到 priv ...

  2. maven加载springboot project

    maven加载springboot project   1● 下载项目 2● 构建project mvn install mvn package   3● idea加载 4● run启动   ==== ...

  3. PHP设置凌晨时间戳

    这种需求应是很常见的,但一直没有时间整理. 一天可以领取2次奖励,今天领完了那就等明天再来. 这里面涉及到一个很重要的一点就是凌晨12点的时间戳,以前一直在前端去做判断.最近发现在后端用PHP获取凌晨 ...

  4. GNOME 系统设置

    详细的GNOME系统设置全文,参见这里. 以下摘录使用到的部分. 1. 在任务栏上显示日期或周几(二选一).秒数 $ gsettings set org.gnome.desktop.interface ...

  5. C++结束进程 并能显示其父进程

    声明:有些网友有可能在CSDN博客上看到过相同的文章,因为本人有两个账号...请不要误会,均为原创 这个程序功能强大哦~~ #include <cstdio> #include <w ...

  6. python编程学习--Pygame - Python游戏编程入门(0)---转载

    原文地址:https://www.cnblogs.com/wuzhanpeng/p/4261015.html 引言 博客刚开,想把最近学习的东西记录下来,算是一种笔记.最近打算开始学习Python,因 ...

  7. 数据结构~Sqlserver索引使用的B树

    B树相关概念 在B-树中查找给定关键字的方法是,首先把根结点取来,在根结点所包含的关键字K1,…,Kn查找给定的关键字(可用顺序查找或二分查找法),若找到等于给定值的关键字,则查找成功:否则,一定可以 ...

  8. Centos 安装dhcp及简单配置

    install yum -y install dhcp file /etc/dhcp/dhcpd.conf eg:-------------------------------- ddns-updat ...

  9. 21. Merge Two Sorted Lists★

    题目内容:Merge two sorted linked lists and return it as a new list. The new list should be made by splic ...

  10. 关于基于LinphoneSDK通话项目开发中遇到的相关问题

    在之前小学期的项目开发当中,我们小组进行的是使用网上开源的LinphoneSDK来开发一款Android端的VOIP电话APP. 因为网上关于这个SDK在安卓端的开发文档相当少,所以我们只能根据少量的 ...