扫微信小程序码实现网站登陆实现解析


Posted in Javascript onAugust 20, 2019

使用扫小程序码登陆网站

网络上关于实现本本功能的文章很多,但是给出案列的几乎没有,今天笔者实现用小程序码实现网站登陆,体验地址如下

https://idea.techidea8.com/open/idea.shtml?id=5

思路

核心流程

扫微信小程序码实现网站登陆实现解析

关键流程

建立场景sceneid和websocket的绑定关系

获得sceneid

场景ID可以前端生成,也可以后端生成,只需要保证sceneid的同一时间唯一性即可。

前端生成可以采用随机数加时间戳的形式,也可以用uuid算法

//时间戳
var sceneid ="scend-" + new Data().getTime() + Math.ceil(Math.random()*888888+1000000);

建立websocket

var ws = new WebSocket("ws://192.168.0.106/websocket?clientid="+sceneid )
ws.onopen=function(env){
  console.log(env)
} 
ws.onmessage=function(env){
  var data = env.data;
  //这个data 就是后端发来的用户数据
}

后端建立websocket

后端采用go语言github.com/gorilla/websocket包建立websocket.因为golang 非常适合高并发场景。

func (ctrl *PushCtrl) websocket(w http.ResponseWriter, req *http.Request) {
  //fmt.Printf("%+v",request.Header)
  //todo 检验接入是否合法
  //checkToken(userId int64,token string)
  query := req.URL.Query()
  clientid := query.Get("clientid")
  conn, err := (&websocket.Upgrader{
    CheckOrigin: func(r *http.Request) bool {
      return true
    },
  }).Upgrade(w, req, nil)

  if err != nil {
    log.Println(err.Error())
    return
  }
  clientMap.Store(clientid, conn)
  go func(clientId string, conn *websocket.Conn) {
    //处理出错信息
    defer func() {
      conn.Close()
      clientMap.Delete(clientid)
    }()
    for {
      _, _, err := conn.ReadMessage()
      if err != nil {
        log.Println(err.Error())
        return
      }
    }
  }(clientid, conn)
}

我们采用sync.map建立sceneid和websocket的对应关系

clientMap.Save(sceneid,conn)

对于因为异常断开的con我们需要移除

clientMap.Delete(sceneid)

获得小程序二维码

获得小程序的accesstoken

小程序access 请求接口如下

``

该接口日使用频率有限制,因此我们需要将这些数据缓存起来,缓存方案很多,有redis,也有内存,我们这里直接用一个变量即可存储

accesstoken :=""
func GetAccessToken() string{
  return accesstoken 
}
func RefreshAccessToken()string{
  url = ""
  resp := httpget(url)
  //resp 是一个包含accesstoken的json字符串,我们解析这个json即可
  accesstoken = decodeaccesstokenfromjson(resp)
  return accesstoken 
}

我们还需要一个滴答计数器用来刷新accesstoken,accesstoken 的有效期是7200秒,我们4000秒刷新一次accesstoken 即可

func refreshAccessToken(){
  ticker := time.NewTicker(time.Second *4000)
  for{
    select {
      case <-ticker.C:
        RefreshAccessToken()
    }
  }
}

在init.go 中的init方法中启动协程

go refreshAccessToken()

小程序二维码编程技巧

小程序二维码请求接口如下

https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESSTOKEN

由于该链接会返回俩种结果

错误返回Json

{
"errcode":400001,
"errmsg":"什么什么原因"
}

正确返回j图片buffer

这是一个二进制码流,因此我们需要对返回结果进行标准化处理

我们建议一种标准化结果

{
code:0,
data:"",
msg:"结果说明"
}

|参数|说明|

|-|-|-|

|code|标识成功或者失败,200为成功,400为失败|

|data|图片的base64格式编码|

|msg|结果说明,或者出错提示|

代码示例如下

url := fmt.Sprintf("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s", token)
ret, err := util.PostJSON(url, arg)
if err != nil {
    util.FailMsg(w, err.Error())
    return
}
jsonstr := string(ret)
if strings.Contains(jsonstr, "errmsg") {
  util.FailMsg(w, jsonstr)
  return
} else {
  base64data := base64.StdEncoding.EncodeToString(ret)
  util.RespOk(w, "data:image/png;base64,"+base64data)
}

其中util是笔者封装的常用工具包

常用工具包

扫微信小程序码实现网站登陆实现解析

前端请求成功后获得data,可以利用$("#qrcode").attr("src",res.data)刷新图片二维码

function refreshqrcode(){
  clientId = "scene-"+new Date().getTime();
  var api = restgo.buildapi("miniapp/getwxacodeunlimit")
  restgo.post(api,{"scene":clientId}).then(res=>{
    if(res.code==200){
      $("#qrcode").attr("src",res.data)
    }else{
      alert(res.msg)  
    }
    intiwebsocket()
  },res=>{
    alert(res.msg)
  })
}

小程序处理关键点

采用好的框架

我们编程过程才用了uniapp,这个框架不错,完全是vue的语法,

一套代码可以生成H5/小程序/android/ios

我们采用了vue的watch特性,通过监听userid来确定是否发送信息

watch:{
   userid:function(a,b){      
      if(a==0){
        return 
      }      
      this.loaddata()
      //如果clientid是空的说明不是扫码进来的  
      if(!this.clientid){
        return 
      }
//如果是扫码进来的,那么我们还需要推送消息到服务器后端
server.PublishMsg(this.clientid,this.userid,this.role,this.avatarUrl,this.nickName).then(res=>{
        tip.error(res.msg)
      },res=>{
        tip.error(res.msg)
      })      
   }
 }

获取sceneid

我们通过onload方法获得sceneid

onLoad(arg) {
    if(!!arg && !!arg.scene){
          this.clientid = decodeURIComponent(arg.scene)
    }        
  },

核心代码如下

通过gotUserInfo获得用户头像、昵称等,通过uni.login获得code

gotUserInfo :function(e) {
       //获得用户头像、昵称、
       uni.login(
       {
         success:(res) =>{
              //通过wx.login获得code
              userInfo.code = res.code
                        //统一传递到后端   
            this.authwithcode(userInfo)
         }
       }
       )
      }
     },
    authwithcode:function(userInfo){
            //code获得openid在后端做,做了后继续去查User表
      server.AuthWithCode(userInfo).then(res=>{
          //如果这个openid绑定了用户                                  
          if(res.data.id>0){
            //这里res.data 就是user对象,可以继续操作
            return ;
          }
          //如果没有那么注册
          server.RegisterWithOpenId(res.data.mini_openid,userInfo.avatarUrl,userInfo.nickName)#.then(res=>{
            //注册成功则返回
            //这里res.data 就是user对象可以继续操作            
          },res=>{
            tip.error(res.msg)
          })
        },res=>{
          tip.error(res.msg||"");
        })
      }
    },

体验地址

本文所有应用体验地址如下

互联网行业解决方案吧https://idea.techidea8.com/open/idea.shtml?id=5

关于代码

代码获得地址

小程序码登陆

代码配置

请认真阅读readme.md

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript与webservice的通信实现代码
Dec 25 Javascript
ASP.NET jQuery 实例11 通过使用jQuery validation插件简单实现用户登录页面验证功能
Feb 03 Javascript
实现网页页面跳转的几种方法(meta标签、js实现、php实现)
May 20 Javascript
浅析创建javascript对象的方法
May 13 Javascript
解析JavaScript中的字符串类型与字符编码支持
Jun 24 Javascript
AngularJS通过$sce输出html的方法
Sep 22 Javascript
微信小程序实现提交input信息到后台的方法示例
Jan 19 Javascript
vue App.vue中的公共组件改变值触发其他组件或.vue页面监听
May 31 Javascript
js实现页面多个日期时间倒计时效果
Jun 20 Javascript
vue实现二级导航栏效果
Oct 19 Javascript
如何正确解决VuePress本地访问出现资源报错404的问题
Dec 03 Vue.js
jQuery实现动态向上滚动
Dec 21 jQuery
vue+element-ui+axios实现图片上传
Aug 20 #Javascript
vue element upload实现图片本地预览
Aug 20 #Javascript
JS中的算法与数据结构之集合(Set)实例详解
Aug 20 #Javascript
Vue + Element UI图片上传控件使用详解
Aug 20 #Javascript
微信小程序项目总结之记账小程序功能的实现(包括后端)
Aug 20 #Javascript
ES6中Symbol、Set和Map用法详解
Aug 20 #Javascript
Vue+Element UI+vue-quill-editor富文本编辑器及插入图片自定义
Aug 20 #Javascript
You might like
php基础知识:类与对象(2) 自动加载对象
2006/12/13 PHP
php中的实现trim函数代码
2007/03/19 PHP
php 生成随机验证码图片代码
2010/02/08 PHP
php 判断字符串中是否包含html标签
2014/02/17 PHP
php计算到指定日期还有多少天的方法
2015/04/14 PHP
PHP实现文件上传后台处理脚本
2020/03/04 PHP
CheckBox 如何实现全选?
2006/06/23 Javascript
Jquery带搜索框的下拉菜单
2013/05/06 Javascript
Bootstrap显示与隐藏简单实现代码
2017/03/06 Javascript
JSONP基础知识详解
2017/03/19 Javascript
jQuery选择器之属性筛选选择器用法详解
2017/09/19 jQuery
JavaScript new对象的四个过程实例浅析
2018/07/31 Javascript
vue中引入第三方字体文件的方法示例
2018/12/17 Javascript
this.$toast() 了解一下?
2019/04/18 Javascript
一篇文章介绍redux、react-redux、redux-saga总结
2019/05/23 Javascript
创建nuxt.js项目流程图解
2020/03/13 Javascript
JS如何判断对象是否包含某个属性
2020/08/29 Javascript
python安装以及IDE的配置教程
2015/04/29 Python
Python 遍历列表里面序号和值的方法(三种)
2017/02/17 Python
Python 逐行分割大txt文件的方法
2017/10/10 Python
python 限制函数调用次数的实例讲解
2018/04/21 Python
Django集成搜索引擎Elasticserach的方法示例
2019/06/04 Python
新建文件时Pycharm中自动设置头部模板信息的方法
2020/04/17 Python
Python API 操作Hadoop hdfs详解
2020/06/06 Python
python 删除系统中的文件(按时间,大小,扩展名)
2020/11/19 Python
python中slice参数过长的处理方法及实例
2020/12/15 Python
CSS3弹性盒模型flex box快速入门心得(必看篇)
2016/05/24 HTML / CSS
HTML5新增加标签和功能概述
2016/09/05 HTML / CSS
耐克波兰官方网站:Nike波兰
2019/09/03 全球购物
全神贯注教学反思
2014/02/03 职场文书
函授大学生自我鉴定
2014/02/05 职场文书
构建高效课堂实施方案
2014/03/13 职场文书
俞敏洪一分钟演讲稿
2014/08/26 职场文书
朋友聚会开场白
2015/06/01 职场文书
Python源码解析之List
2021/05/21 Python
ubuntu如何搭建vsftpd服务器
2022/12/24 Servers