微信小程序登录那些事

最近团队在开发一款小程序,都是新手,一边看文档,一边开发。在开发中会遇到各种问题,今天把小程序登录这块的流程整理下,做个记录。

小程序的登录跟平时自己APP这种登录验证还不太一样,多了一个角色,那就是微信服务器。

根据微信官方提供的登录流程时序图可以清楚的了解小程序登录需要多少个步骤,下面我们来总结下:

  • 小程序启动,通过wx.login()获取code
  • 开发者服务器需要提供一个登录的接口,参数就是小程序获取的code
  • 登录接口收到code后,调用微信提供的接口进行code的验证
  • 得到验证结果,成功后能得到一个session_key和openid
  • 生成一个自定义的key, 将session_key和openid跟自定义的key关联起来
  • 将自定义的key返回给小程序
  • 每次请求都带上key, 后端根据key获取openid识别当前用户身份

首先code是微信给的,如果你随意生成code去验证肯定是无效的,只有微信给的code才有效。code传到开发者自己的服务后,再去问微信:

Hi 哥们,我这个code是有效的还是无效的啊?

微信会告诉你是有效还是无效,有效的情况下还会给你一个用户的标识,也就是openid,同时还会有一个session_key,也就是会话的key。session_key的有效期默认是2小时,当用户一直在使用小程序的话会自动刷新,这个是由微信这边来维护的。

注意:

  1. 会话密钥?session_key?是对用户数据进行?加密签名?的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥
  2. 临时登录凭证 code 只能使用一次

所以我们要为session_key创建别名,这个别名关联的哪个用户只有我们自己知道,唯一需要做的工作就在这块。

我推荐2种方式来做关联:

第一种:
随机生成key, 关联openid,存入redis中,当请求带入key,直接从redis中获取openid得到当前用户信息,这个其实也就是我们自己去维护了会话信息

第二种:
采用JWT生成token,将openid绑定到token中,将token返回给小程序,请求的时候带上token,通过解析token得到用户信息。

下面我们以第二种方式来进行讲解,会贴上部分代码:

小程序中在app.js中的onLaunch方法中增加获取code方法,并且调用后端的登录接口获取token:

wx.login({
      success: function (res) {
        var code = res.code;
        if (code) {
          console.log('app启动获取用户登录凭证:' + code);
          let params = { "code": code };
          let result = config.requestHttp(config.url.userLogin, 'POST', params)
          result.then(res => {
            let data = res.data
            if (data.code == 200) {
              wx.setStorageSync("login_token", data.data.token);
            }
          }).catch(err => {
            console.log(err)
          });
        } else {
          console.log('获取用户登录态失败:' + res.errMsg);
        }
      }
})

userLogin接口则根据小程序的code去调用微信接口验证:

// 小程序获取SessionKey接口地址
String loginUrl = "https://api.weixin.qq.com/sns/jscode2session";
String url = loginUrl + "?appid=%s&secret=%s&grant_type=%s&js_code=%s";
url = String.format(url, appid, appSecret, grantType, param.getCode());
String result = restTemplate.getForObject(url, String.class);
Map<String, Object> map = JsonUtils.toBean(Map.class, result);
// 请求成功
if (map.containsKey("session_key")) {
    String openid = map.get("openid").toString();
    // 第一次保存到用户表,生成JWT TOKEN返回
}

小程序端需要将 wx.request()封装成一个通用的方法,所有跟后台交互都用这个方法来调用接口,我们可以在这个方法中设置登录之后获取的Token。这样每次请求都会将Token塞到请求头中,我们在网关中就可以获取这个Token进行解析验证。

//请求封装
function requestHttp(url, method, data) {
  //请求头设置
  var header = {
    Authorization: wx.getStorageSync("login_token")
  }
  return new Promise((resolve, reject) => {
    wx.request({
      url: config.home_config + url,
      data: data,
      header: header,
      method: method,
      success: (res => {
        if (res.data.code === 200) {
          resolve(res)
        } else {
          reject(res)
        }
      }),
      fail: (res => {
        reject(res)
      })
    })
  })
}

Zuul中进行验证:

  RequestContext ctx = RequestContext.getCurrentContext();
  HttpServletRequest request = ctx.getRequest();
  String token = request.getHeader("Authorization");
  if (StringUtils.isBlank(token)) {
            ctx.setSendZuulResponse(false);
            ctx.set("isSuccess", false);
            ctx.setResponseBody(JsonUtils.toJson(Response.fail("非法请求【缺少Authorization】", ResponseCode.NO_AUTH_CODE)));
            ctx.getResponse().setContentType("application/json; charset=utf-8");
            return null;
  }

  // 验证Token是否有效
  JWTResult jwResult = JWTUtils.checkToken(token);
  if (!jwResult.isStatus()) {
            ctx.setSendZuulResponse(false);
            ctx.set("isSuccess", false);
            ctx.setResponseBody(JsonUtils.toJson(Response.fail(jwResult.getMsg(), jwResult.getCode())));
            ctx.getResponse().setContentType("application/json; charset=utf-8");
            return null;
   }
   ctx.addZuulRequestHeader("loginUserId", jwResult.getUid());
   return null;

验证成功后将用户ID设置到请求头中,传递给后端服务使用。

使用JWT必然有一个问题是Token的失效问题,我这边失效时间设置的为2个小时,正常的话用户打开小程序,使用不可能连续超过2个小时,登录的逻辑是在app.js中做的,只要下次进去token就会重新申请。不过这个也可以调整,比如稍微长一点。

核心就是用户的认证交给了微信,只要微信告诉我们认证成功了,我们就可以自己接管会话信息了。

欢迎加入我的知识星球,一起交流技术,免费学习猿天地的课程(http://cxytiandi.com/course

原文地址:https://www.cnblogs.com/yinjihuan/p/10464303.html

时间: 2024-08-28 09:53:23

微信小程序登录那些事的相关文章

SpringBoot整合微信小程序登录

1. 开发前准备 1.1 前置知识 java基础 SpringBoot简单基础知识 1.2 环境参数 开发工具:IDEA 基础环境:Maven+JDK8 所用技术:SpringBoot.lombok.mybatisplus.微信小程序 SpringBoot版本:2.1.4 1.3 涉及知识点 微信小程序登录流程 2. 微信小程序登录流程 微信小程序登录流程涉及到三个角色:小程序.开发者服务器.微信服务器 三者交互步骤如下: 第一步:小程序通过wx.login()获取code. 第二步:小程序通过

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

先上效果图 点击授权按钮后可以显示部分资料和头像,点击修改资料可以修改部分资料. 流程 1.使用微信小程序登录和获取用户信息Api接口 2.把Api获取的用户资料和code发送给django后端 3.通过微信接口把code换取成openid 4.后端将openid作为用户名和密码 5.后端通过JSON web token方式登录,把token和用户id传回小程序 6.小程序将token和用户id保存在storage中 下次请求需要验证用户身份的页面时,在header中加入token这个字段 微信

flask与微信小程序登录(后端)

开发微信小程序时,接入小程序的授权登录可以快速实现用户注册登录的步骤,是快速建立用户体系的重要一步.这篇文章将介绍 python + flask + 微信小程序实现用户快速注册登录方案(本文主要进行后端逻辑的梳理,小程序端逻辑只写了必要的部分,如有需要,请点击连接阅读官方开发文档) 官方给出的微信小程序登录时序图如下: 这个流程分为两大部分: 小程序使用 wx.login() API 获取 code,并由开发者后端服务器换取open_id 和 session_key,小程序使用 wx.getUs

微信小程序--登录流程梳理

前言 微信小程序凡是需要记录用户信息都需要登录,但是也有几种不同的登录方式,但是在小程序部分的登录流程是一样的.之前就朦朦胧胧地用之前项目的逻辑改改直接用了,这个新项目要用就又结合官方文档重新梳理了下,并记录一下,好记性不如烂笔头嘛,哈哈. 几种登录流程设计 利用OpenId 创建新用户 这种方式我的理解大体上就是一种静默登录,获取用户信息之后解密用户信息并通过OpenId直接创建新用户 利用Unionid 创建新用户 这种方式的特点是可以利用Unionid实现多个小程序.公众号.已有登录体系的

微信小程序登录 .net 后端实现

1:前端获取用户凭证code 传送请求获得openId(用户唯一标识)     在页面的Onlaunch 方法中,调用wx.login 方法 https://developers.weixin.qq.com/miniprogram/dev/api/wx.login.html 这一步获取登录凭证,通过凭证调用本地后台接口,获取用户openId sessionKey等,本地后台的接口调用方法参考第四步 注意点: 1:通常我们会把用户的session_key 存取到后台的session会话中,但是在微

[转]微信小程序登录数据解密以及状态维持

本文转自:http://www.cnblogs.com/cheesebar/p/6689326.html 学习过小程序的朋友应该知道,在小程序中是不支持cookie的,借助小程序中的缓存我们也可以存储一些信息,但是对于一些比较重要的信息,我们需要通过登录状态维持来保存,同时,为了安全起见,用户的敏感信息,也是需要加密在网络上传输的. 前台,service.封装了http请求,同时封装了getSession(通过code获取服务器生成的session).getUserInfo(获取用户信息).ge

对于微信小程序登录的理解图

有两种获取用户信息的方案. 1.不包含敏感信息openId 的json对象(包含:nickname.avatarUrl等基本信息) 2.包含敏感信息openId的基本信息. 第一种获取方案 1.首先调用wx.login()接口 让用户授权验证,也就是我们肉眼观察到的,你是否对xxxxx授权这种信息. 2.用户成功授权后,调用wx.getUserInfo() 接口获取用户信息. 完整代码如下 wx.login({ success:function(){ wx.getUserInfo({ succe

微信小程序登录逻辑

wx.getStorage({ key: 'session_id', success: function(res) { //如果本地缓存中有session_id,则说明用户登陆过 console.log("本地缓存中的session_id:" + res.data) //判断微信服务器session是否有效 wx.checkSession({ success: function(res) { console.log("处于登录态,session有效"); //如果已

微信小程序登录流程

微信登陆流程 微信多个载体(APP微信授权,微信公众号授权登陆),openId是不一致的,但是unionId是一致的 所以在走流程时, 先判断unionId在数据库中存在不存在 存在,拿unionId去数据库换token,获取用户信息,更新openId,---首页 不存在,在启动页,让用户点击授权登陆,获取用户信息,再进行手机号授权 微信授权手机号 ---首页 登陆注册手机号 ---首页 代码方面: 进入启动页 wx.login();//获取code,code只能获取一次 将code传给后端,换