微信小程序登录流程解析

简介: 微信官方文档有小程序的登录流程时序图,本文围绕这张图从0到1做更具体的解析。微信小程序的登录看上去好像很复杂,实际上只是不同的接口调用、字段返回,整个过程有3方在参与:小程序、开发者服务器、微信服务器。

微信官方文档有小程序的登录流程时序图,本文围绕这张图从0到1做更具体的解析。微信小程序的登录看上去好像很复杂,实际上只是不同的接口调用、字段返回,整个过程有3方在参与:小程序、开发者服务器、微信服务器。


首先,看一下微信官方时序图:


11.png


根据上面的图,可以分为以下几步:

第1步 - 小程序:小程序前端调用wx.login得到code,再传给开发者服务器。

code是临时登录凭证,有效期为5分钟、只能使用一次,每次调用wx.login,都会返回不同的code。把code、appid、appsecret一起传到开发者服务器,由它调用微信接口换取相关信息。如果需要检验账号和密码,那么除了上述这3个参数,还可以加上账号密码,一起请求开发者服务器。

appid和appsecret需要在「小程序后台->开发->开发管理->开发设置->开发者ID」找到。这2者必须属于当前小程序,如果拿其它小程序的开发者ID则会出现报错。

appid和appsecret:


12.png


开发者服务器接口地址必须为https协议,域名必须经过ICP备案,同时需要在「小程序后台->开发->开发管理->开发设置->服务器域名」 提前配置(测试环境除外)。为了安全起见,建议用POST的请求方式。

开发者服务器域名配置:


13.png


wx.request的超时时间默认为60秒,为了避免用户因网络异常或服务器问题等待回包太久,可以在app.json设置wx.request的超时时间,超时则触发fail回调。


"networkTimeout": {
  "request": 3000
}


代码示例(为了方便演示,把密钥放到了前端请求):


wx.login({
  success: (res) => {
    var code = res.code;
    var app_id = "你的app_id";
    var app_secret = "你的app_secret";
    wx.request({
      url: "开发者服务器接口地址",
      method: "POST",
      header: {
        "content-type": "application/x-www-form-urlencoded"
      },
      data: {
        //完整写法是app_id:app_id,这是简写
        app_id, app_secret, code
      },
      success: (res) => {
        console.log("打印返回结果", res)
      }
    })
  }
})

第2步 - 开发者服务器:调用微信服务器接口,得到openid、session_key、unionid。unionid需要满足一定条件才能返回,在本文不展开。在这个步骤,如果出现错误的话,微信服务器会返回errcode(错误码)。此外,在这个过程校验账号和密码之后,可以把账号密码等信息和openid进行绑定。

微信服务器接口地址:

https://api.weixin.qq.com/sns/jscode2session?appid=<your_appid>&secret=<your_appsecret>&js_code=<your_code>&grant_type=authorization_code

服务器代码示例:

$app_id=$_POST['app_id'];
$app_secret=$_POST['app_secret'];
$code=$_POST['code'];
$url='https://api.weixin.qq.com/sns/jscode2session?appid='.$app_id.'&secret='.$app_secret.'&js_code='.$code.'&grant_type=authorization_code';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER,0);
curl_setopt($ch, CURLOPT_POST, 1);
$output = curl_exec($ch);
curl_close($ch);
echo $output;


控制台打印:


14.png


从上面可以看到,微信服务器返回了openid和session_key。openid为用户在当前小程序的唯一标识,不同用户在小程序的openid不同,用户删除小程序、清空缓存不改变openid;session_key为开发者服务器和微信服务器的会话密钥,用于加解密数据,随着用户越频繁地使用小程序,session_key的有效期会越长。

第3步 - 开发者服务器:根据微信服务器返回的信息,自定义登录态。openid和session_key因为涉及到数据隐私,所以不直接发往小程序,而是在开发者服务器根据这2者自定义登录态,也就是定义token,再通过wx.setStorage把token写入本地数据缓存。至于怎么定义token,不同语言和不同项目的写法不一样,在这不再展开。

不同小程序有各自的本地缓存空间,彼此之间是分隔的,每个缓存空间大小是10M,如果超出10M再写入数据时,会触发fail回调。当然同一个设备的不同微信用户之间的缓存也是分隔的。

在第1步的代码,我们加上存储token的语句:


wx.login({
  success: (res) => {
    var code = res.code;
    var app_id = "你的app_id";
    var app_secret = "你的app_secret";
    wx.request({
      url: "开发者服务器接口地址",
      method: "POST",
      header: {
        "content-type": "application/x-www-form-urlencoded"
      },
      data: {
        app_id, app_secret, code
      },
      success: (res) => {
        console.log("打印返回结果", res);
        //存储到全局变量中,方便调用
        this.globalData.token = res.token;
        //把token放在本地缓存
        wx.setStorage({
          key: "token",
          data: res.token
        })
      }
    })
  }
})


当用户再次打开小程序时,就带上storage请求开发者服务器(在app.js定义),判断登录态有没有过期,而不用每次打开小程序都要重新登录:


onLaunch: function () {
  var that = this;
  //从本地缓存同步获取token
  var token = wx.getStorageSync("token");
  if (token && token.length) { //判断是否有token
    //验证token是否有效
    wx.request({
      url: "开发者服务器检验token的接口地址",
      method: "POST",
      header: {
        "content-type": "application/x-www-form-urlencoded"
      },
      data: {
        token
      },
      success: (res) => {
        if (res.status == "correct") {  //假设token正确
          //返回登录状态,存储到全局变量中,方便调用
          this.globalData.token = res.token;
        } else {
          that.login()  //重新登录,假设wx.login放到login()
        }
      }
    })
  } else {  //如果没有token
    that.login()  //重新登录,假设wx.login放到login()
  }
}

当然,如果你的登录态有效期以session_key为准,那么可以用wx.checkSession检查session_key有没有过期。wx.checkSession示例:

onLaunch: function() {
  wx.checkSession({
    success() {
      //session_key没过期,返回登录状态
    },
    fail() {
      // session_key过期,重新登录
    }
  })
}



Q&A



Q1:wx.login需要用户点击按钮授权吗?

A:不需要,这个行为是静默的,用户层面不会有感知。

Q2:wx.login返回的code只有5分钟的时效性,这样的好处是什么?

A:对于侵略者来说,想要在5分钟之内列举所有code,然后频繁请求开发者服务器试图获取真实用户信息,这无疑难度加大、容易被识别。

Q3:AppId和AppSecret都是隐私数据吗?会不会涉及安全风险?

A:AppId是公开信息,不会涉及安全风险,用户查询AppId的路径为「小程序右上角->小程序名称->更多资料->AppId」;AppSecret是隐私数据,不应该被公开泄露,一旦泄露需要到小程序后台重置。

本文作者:朱顺意

声明:本文为 脚本之家专栏作者 投稿,未经允许请勿转载。

相关文章
|
1月前
|
小程序 API
微信小程序——授权登录
微信小程序——授权登录
26 0
|
2月前
|
算法 数据处理 开发者
FFmpeg库的使用与深度解析:解码音频流流程
FFmpeg库的使用与深度解析:解码音频流流程
43 0
|
1月前
|
数据采集 机器学习/深度学习 数据可视化
数据科学项目实战:完整的Python数据分析流程案例解析
【4月更文挑战第12天】本文以Python为例,展示了数据分析的完整流程:从CSV文件加载数据,执行预处理(处理缺失值和异常值),进行数据探索(可视化和统计分析),选择并训练线性回归模型,评估模型性能,以及结果解释与可视化。每个步骤都包含相关代码示例,强调了数据科学项目中理论与实践的结合。
|
4天前
|
算法 Linux 调度
xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程
xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程
10 1
xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程
|
4天前
|
Linux 调度 数据库
|
4天前
|
Linux API 调度
xenomai内核解析-xenomai实时线程创建流程
本文介绍了linux硬实时操作系统xenomai pthread_creta()接口的底层实现原理,解释了如何在双内核间创建和调度一个xenomai任务。本文是基于源代码的分析,提供了详细的流程和注释,同时给出了结论部分,方便读者快速了解核心内容。
7 0
xenomai内核解析-xenomai实时线程创建流程
|
6天前
|
供应链 监控 安全
全面剖析:新页ERP系统不为人知的一面,以及系统的工作流程解析!
全面剖析:新页ERP系统不为人知的一面,以及系统的工作流程解析!
|
14天前
|
缓存 Java 开发者
10个点介绍SpringBoot3工作流程与核心组件源码解析
Spring Boot 是Java开发中100%会使用到的框架,开发者不仅要熟练使用,对其中的核心源码也要了解,正所谓知其然知其所以然,V 哥建议小伙伴们在学习的过程中,一定要去研读一下源码,这有助于你在开发中游刃有余。欢迎一起交流学习心得,一起成长。
|
27天前
|
数据采集 数据可视化 数据挖掘
Seaborn实战:从数据清洗到可视化全流程解析
【4月更文挑战第17天】在数据分析中,Seaborn是用于数据可视化的重要工具,同时也辅助数据清洗。本文通过实例展示了如何利用Seaborn从数据清洗(包括导入数据、处理缺失和异常值)到数据探索(描述性统计、分组统计和可视化探索)。接着,文章详细讲解了数据可视化,包括分类和数值数据的图表以及高级图表如小提琴图、箱形图和热力图。最后,介绍了Seaborn与其他工具(如Pandas和Matplotlib)的结合使用,强调了数据可视化的迭代优化过程。学习并掌握Seaborn能提升数据分析和展示的效率。
|
1月前
|
小程序 前端开发 API
深入解析微信小程序全栈开发流程
【4月更文挑战第12天】本文详述了微信小程序全栈开发流程,从需求分析到发布运营。首先,需进行需求分析与规划,明确目标用户和功能。接着,前端开发使用WXML和WXSS构建页面,JavaScript处理逻辑,结合微信API实现交互。后端开发涉及数据库设计、业务逻辑处理、API接口开发及服务器运维。完成后的调试与测试确保质量,最后发布并持续优化。全栈开发涉及多种技能,理解整个流程对创建优质小程序至关重要。

推荐镜像

更多