我们一般都是先获取到微信的 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. git提交步骤

    1,为了确定在本地分支下操作,可以用命令查看一下是否在本地分支 git branch 2,可以查看状态,是否添加了哪些内容 git status 3,如果确认无误,使用命令进行提交本地代码,并加上注释 ...

  2. 推荐好用的css调试工具,两个

    一:Emmet LiveStyle(http://livestyle.io/) CSS,LESS和SCSS的第一个双向实时编辑工具. 官网说只适用与谷歌跟sublime,可以自行测试   1.subl ...

  3. vue-swiper 基于Vue2.0开发 轻量、高性能轮播插件

    vue-swiper 基于 Vue2.0 开发,基本满足大部分功能 轻量.高性能轮播插件.目前支持 无缝衔接自动轮播.无限轮播.手势轮播 没有引入第三方库,原生 js 封装,打包之后只有 8.2KB ...

  4. centos 日志文件

    以下介绍的是20个位于/var/log/ 目录之下的日志文件.其中一些只有特定版本采用,如dpkg.log只能在基于Debian的系统中看到./var/log/messages — 包括整体系统信息, ...

  5. jdbc模板

    public class JdbcTest { public static void main(String[] args) { //数据库连接 Connection connection = nul ...

  6. go-ethereum源码分析 PartIII 共识流程

    A: js指令转化为新transaction 在web3上操作流程 1. import to web3 2. connect to peers 3. read local key store 4. d ...

  7. 解决flask的502错误:upstream prematurely closed connection while reading response header from upstream

    我在使用 tiangolo/uwsgi-nginx-flask 部署flask应用的时候,经常运行一会儿就出现502错误,重新启动容器后,就恢复. 且经常会出现数据更新后,刷新结果不一致. docke ...

  8. asp解码.net传参

    get传参时 asp默认使用gbk解码?了解的朋友指点下,谢谢 .net向asp传参时注意urlencode加密编码使用gb2312 附:任何语言的数据交互都要确保接收双方的编码一致

  9. 【基于微信小程序的社区电商平台】Alpha迭代心得

    项目团队:小豆芽 开发周期:11.5-12.2(Alpha版本) 设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 解决问题:当前电商平台卖家买家角 ...

  10. optimal-account-balancing

    一群朋友去度假,有时互相借钱. 例如,爱丽丝为比尔的午餐支付了 10 美元.后来克里斯给爱丽丝 5 美元搭出租车.我们可以假设每笔交易为一个三元组(X,Y,Z),这意味着第 X 个人借给第 Y 个人  ...