微信小程序开发之登录逻辑记录微信小程序登录分析

微信小程序登录分析

以下后端代码都是在node egg框架内执行,切勿搞混了,分享的只是登录注册思路,想要编程学的好,就好多动手

按照微信官方给的流程图,我们得知,当小程序需要注册登录时,必须从小程序客户端通过wx.login获取对应的code,发送到后端通过微信官方接口获取唯一的识别码 (openid)

接口在此 api.weixin.qq.com/sns/jscode2…

image.png

小程序注册的两种方式

第一种

通过手动点击授权登录注册,如果当前用户第一次进入并点击授权,就会先注册在登陆,如果已注册,就直接登录

image.png

给点击授权绑定一个名叫login的点击事件,通过bindtap属性绑定<view class="authorization" bindtap="login">点击授权</view>

在登录页面的js文件内 定义一个 login方法,内容如下

login(){
      //当用户点击授权时,执行login方法,并且通过wx.getUserProfile开放接口获取到当前用户的信息,
      wx.getUserProfile({
        desc: '用于用户注册', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
        success: (res) => {
          //在成功回调里把返回的userinfo解构出来,并存到本地缓存里,方便后续各个页面显示当前用户的信息,例如“我的”页面会显示用户头像和昵称等,再定义一个userInfo 变量接收下用户资料,后续一起发送到后端
          let userInfo = res.userInfo;
          wx.setStorageSync('userInfo', userInfo);
          this.setData({
            userInfo,
            hasUserInfo: true
          })
          console.log(res);
          //代码执行到这里时,会执行wx.login这个开放接口获取微信用户的临时凭证
          wx.login({
            success (res) {
              //当wx.login返回结果后把唯一凭证取出来,并存到上面新建的userInfo变量内
              userInfo.code = res.code;
              //把变量通过post方式传递到后端
              axios.post({url: '/wxlogin',data:userInfo})
              .then((data)=>{
                console.log(data);
                wx.setStorageSync('token', data.data.data.token);
              }).catch(e=>{
                console.log(e);
              })
            }
          })
        },
        fail:(res)=>{
          console.log("授权失败",res);
        }
      })
    },
复制代码

后端部分

在controller层新建一个Weixin.ts,同时定义一个wxAuth的方法用户路由执行该方法,并接收小程序发送来的UserInfo

public async wxAuth(){
   const { ctx } = this;

   const userInfo = ctx.request.body;

   //以下两个需要去微信小程序后台那获取,这两个是开发者的APP相关资料,切勿泄露,以下都是我修改过的,所以展示出来没事,一般放在config里面,这样打包编译就不会泄露出来,如果按照以下写,有心人想要获取很容易获取到
   const AppId = 'wxc3e768e332c12f4c';
   const AppSecret = '8fb8e48c87e05cec2762518770fd3f09';

   //通过 微信开放接口获取openid,这一步应该在service层做的,但是我嫌麻烦就写到controller内了,开发时一定要写到service层
   const result = await ctx.curl(`https://api.weixin.qq.com/sns/jscode2session?appid=${AppId}&secret=${AppSecret}&js_code=${userInfo.code}&grant_type=authorization_code`,{
      dataType: "json",
      timeout: 5000,
      method: "GET",
      data: JSON.stringify({})
   })
   if (result.data.errcode === 41008){
      throw new Error("缺少code")
   }
   if (result.data.errcode === 40029){
      throw new Error("code 无效")
   }
   if (result.data.errcode === 45011){
      throw new Error("code 频率限制")
   }
   if (result.data.errcode === -1){
      throw new Error("系统繁忙,请稍后再试")
   }
   if (result.data.errcode === 40163){
      throw new Error("当前code已经被使用")
   }
       /*
       * 当请求成功时,会返回如下格式的数据
       * "data": {
            "session_key": "FSn2szxyuYndSbdowg5Zzw==",
            "openid": "o0teF4mqBhpe-pfa01QK4xc3l4c3"
         }
       * */


   //解构出 session_key和openid
   // @ts-ignore
   const {session_key,openid} = result;


   //组装用户数据,把所需的数据保存下来,方便后续创建用户,当然也要看你的表结构,所需什么数据就组装成什么结构,例如我的是用户表和用户信息表分开的,以下user就是存到userinfo这张表里的所需数据

   let User = {
      opId: openid,
      avatarUrl: userInfo.avatarUrl,
      userName: userInfo.nickName,
      gender: userInfo.gender,
      provider: "WeiXin",
      accessToken: session_key
   }

   // 调用同层的gotoAdmin方法并传递User这个变量,在这个方法内决定是否注册或直接登陆
   await this.goToAdmin(User)
}

public async goToAdmin(_User){
   // const {ctx} = this;

   //通过Try和catch判断是否注册和登录

   try {
      //在Try里面执行service层的用户查询方法,用户存在返回用户信息,如果没有查询到用户,就报错执行catch里面的代码
      //下面就是执行你的后端处理登录的逻辑了,例如token的签发,用户信息的返回等
   }catch (e) {
      //    用户不存在先注册再登陆,例如通过uuid创建用户名等,然后前端传递过来的数据和生成好的用户信息等保存到数据库,再返回数据到小程序
   }
}
复制代码

第二种方式

和上面差不多,在小程序入口文件内执行wx.login,当用户一进来就在后台悄悄地给他注册,当用户点击授权按钮时,就把获取的用户资料发送到后端保存起来,两种方法都可以,一种是授权的同时,注册并保存用户资料,一种是先注册,再保存用户资料