微信小程序登录流程解析

简介: 微信官方文档有小程序的登录流程时序图,本文围绕这张图从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是隐私数据,不应该被公开泄露,一旦泄露需要到小程序后台重置。

本文作者:朱顺意

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

相关文章
|
6天前
|
小程序 API
微信小程序——授权登录
微信小程序——授权登录
26 0
|
6天前
|
前端开发 小程序 JavaScript
电商小程序04实现登录逻辑
电商小程序04实现登录逻辑
|
6天前
|
缓存 前端开发 Java
【二十八】springboot之通过threadLocal+参数解析器实现同session一样保存当前登录信息的功能
【二十八】springboot之通过threadLocal+参数解析器实现同session一样保存当前登录信息的功能
44 1
|
6天前
|
存储 前端开发 Java
Javaweb之SpringBootWeb案例之登录校验功能的详细解析
Javaweb之SpringBootWeb案例之登录校验功能的详细解析
9 0
|
6天前
|
JSON 前端开发 数据安全/隐私保护
Javaweb之SpringBootWeb案例之 登录功能的详细解析
Javaweb之SpringBootWeb案例之 登录功能的详细解析
15 0
|
6天前
|
小程序 前端开发 API
深入解析微信小程序全栈开发流程
【4月更文挑战第12天】本文详述了微信小程序全栈开发流程,从需求分析到发布运营。首先,需进行需求分析与规划,明确目标用户和功能。接着,前端开发使用WXML和WXSS构建页面,JavaScript处理逻辑,结合微信API实现交互。后端开发涉及数据库设计、业务逻辑处理、API接口开发及服务器运维。完成后的调试与测试确保质量,最后发布并持续优化。全栈开发涉及多种技能,理解整个流程对创建优质小程序至关重要。
|
6天前
如何在PC端登录多个微信号?怎么操作免费多开电脑版微信?
如何在PC端登录多个微信号?怎么操作免费多开电脑版微信?
|
6天前
|
数据采集 前端开发 JavaScript
Java网络爬虫实践:解析微信公众号页面的技巧
Java网络爬虫实践:解析微信公众号页面的技巧
|
6天前
|
小程序 前端开发 数据安全/隐私保护
电商小程序03登录页面开发
电商小程序03登录页面开发
|
6天前
|
小程序
TDesign电商小程序模板解析02-首页功能
TDesign电商小程序模板解析02-首页功能

热门文章

最新文章

推荐镜像

更多