实现微信小程序扫码登录

思路

通过已登录小程序去扫web端的一个二维码获取二维码的信息,然后根据这个信息请求服务是否有效。web端监听这个信息的状态,如果这个状态授权那就进入首页。
在这里插入图片描述
在这里插入图片描述

实现

1、 web端登录二维码
web端显示的二维码直接使用antd中QRCode组件。当刷新二维码时,请求服务接口拿到一个唯一code,并且存储在redis,设置时效5分钟左右;

	r.GET("/qr", func(ctx *gin.Context) {
		singcode := ctx.Query("singcode")
		if singcode != "" {
			b, vsingcode := datasource.GetRedisByString(singcode)
			if b == false {
				ctx.JSON(http.StatusOK, gin.H{"code": 404, "singcode": ""})
			} else {
				if vsingcode == "1" {
					ctx.JSON(http.StatusOK, gin.H{"code": 201, "singcode": ""})
				} else if vsingcode != "0" {
					// 确定登录 立即删除
					datasource.DelRedisByString(singcode)
					ctx.JSON(http.StatusOK, gin.H{"code": 202, "singcode": vsingcode})
				}
			}
		} else {
			uuid := uuid.New()
			key := uuid.String()
			datasource.SetRedisByString(key, "0", 5*time.Minute)
			ctx.JSON(http.StatusOK, gin.H{"code": 200, "singcode": key})
		}
	})

2、微信小程序扫码请求服务校验singcode是否有效,并做登录处理
微信小程序侧:


   wx.scanCode({
      onlyFromCamera: true,
      async success (res) {
        console.log(res)
        const { result } = res
        if (result) {
          const [err,] = await checkScanCode(result)
          if (!err) {
            wx.showModal({
              content: '是否登录?',
              success (res) {
                if (res.confirm) {
                  console.log('用户点击确定')
                  scanCode(result)
                } else if (res.cancel) {
                  console.log('用户点击取消')
                }
              }
            })
          } else {
            wx.showToast({
              title: '确认信息失败',
              icon: 'none',
              duration: 2000
            })
          }
        }
        
      }
    })

校验singcode有效性直接去访问redis是否存在key即可:

auth.GET("/checkscancode", func(ctx *gin.Context) {
			singcode := ctx.Query("singcode")
			b, lcode := datasource.GetRedisByString(singcode)
			if singcode == "" || b == false || (b == true && lcode != "0") {
				ctx.JSON(http.StatusBadRequest, "singcode"+lcode)
				return
			}
			datasource.SetRedisByString(singcode, "1", 1*time.Minute)
			ctx.JSON(http.StatusOK, gin.H{"code": 200})
		})

小程序校验有效之后,就弹窗提示登录,确定登录后,请求服务将singcode状态修改,并且将小程序登录账号的id存储下来(通知web端是哪个账号登录)

auth.GET("/scancode", func(ctx *gin.Context) {
			singcode := ctx.Query("singcode")
			b, lcode := datasource.GetRedisByString(singcode)
			if singcode == "" || b == false || (b == true && lcode != "1") {
				ctx.JSON(http.StatusBadRequest, "singcode"+lcode)
				return
			}
			tokenString := ctx.GetHeader("authorization")
			if tokenString == "" {
				ctx.JSON(http.StatusBadRequest, "TOKEN")
				return
			}
			id := uitls.PaserToken(strings.Split(tokenString, "Bearer ")[1], authMiddleware)
			if id == "" {
				ctx.JSON(http.StatusBadRequest, tokenString+"==ID=="+strings.Split(tokenString, "Bearer ")[1])
				return
			}
			info, st := dao.GetUserInfoByPbOpenId("", "", id, "")
			if st == -1 || st == 0 {
				ctx.JSON(http.StatusBadRequest, "-1")
				return
			}
			uuid := uuid.New()
			key := uuid.String()
			datasource.SetRedisByString(key, info.Id, 5*time.Minute)
			datasource.SetRedisByString(singcode, key, 5*time.Minute)
			ctx.JSON(http.StatusOK, key)
		})

3、 web端轮询检测singcode状态
登录的二维码不能长期有效,因此需要去每隔2秒去检查是否要刷新二维码。当小程序扫码确定登录之后,此时返回状态code == 202,这个时候会拿到一个 singcode,这个singcode绑定了扫码账号的用户信息,携带它去请求登录接口,就实现一个扫码登录了。
web端:

 const refreshQrCode = (isout) => {
    getScanCode(isout).then( res => {
      const { code, singcode } = res.data
      if (code === 200) {
        setLoginQrCode(singcode)
      } else if (code === 201) {
        setQrCodeStatus("actived")
      } else  if (code === 404) {
        setQrCodeStatus('expired')
        timer && clearInterval(timer), timer = null;
        return
      } else if (code === 202) {
        timer && clearInterval(timer), timer = null;
        setQrCodeStatus("loading")
        codeSin = singcode
        handleLogin()
        return
      }
      !timer && (timer = setInterval(() => {
        refreshQrCode(singcode)
      }, 2 * 1000))

    }).catch(()=> {
      setQrCodeStatus('expired')
    })
  }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今天也想MK代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值