通过扫小程序码实现网站登陆功能


Posted in Javascript onAugust 22, 2019

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

https://idea.techidea8.com/open/login.shtml

思路

通过扫小程序码实现网站登陆功能

核心流程

关键流程

建立场景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

关于代码

代码获得地址

小程序码登陆

总结

以上所述是小编给大家介绍的通过扫小程序码实现网站登陆功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
原生js实现shift/ctrl/alt按键的获取
Apr 08 Javascript
javascript使用appendChild追加节点实例
Jan 12 Javascript
jscript读写二进制文件的方法
Apr 22 Javascript
jQuery超酷平面式时钟效果代码分享
Mar 30 Javascript
使用BootStrap建立响应式网页——通栏轮播图(carousel)
Dec 21 Javascript
node.js利用redis数据库缓存数据的方法
Mar 01 Javascript
解决VUEX兼容IE上的报错问题
Mar 01 Javascript
Vue实现PopupWindow组件详解
Apr 28 Javascript
Javascript获取某个月的天数
May 30 Javascript
angular 实现下拉列表组件的示例代码
Mar 09 Javascript
vue 输入电话号码自动按3-4-4分割功能的实现代码
Apr 30 Javascript
微信小程序开发打开另一个小程序的实现方法
May 17 Javascript
vue中实现上传文件给后台实例详解
Aug 22 #Javascript
js的新生代垃圾回收知识点总结
Aug 22 #Javascript
JS实现移动端在线签协议功能
Aug 22 #Javascript
jQuery表单选择器用法详解
Aug 22 #jQuery
node实现简单的增删改查接口实例代码
Aug 22 #Javascript
微信小程序实现上传图片裁剪图片过程解析
Aug 22 #Javascript
ES6基础之 Promise 对象用法实例详解
Aug 22 #Javascript
You might like
关于文本留言本的分页代码
2006/10/09 PHP
PHP-FPM之Chroot执行环境详解
2015/08/03 PHP
php str_replace替换指定次数的方法详解
2017/05/05 PHP
PHP 7.1中AES加解密方法mcrypt_module_open()的替换方案
2017/10/17 PHP
PHP getID3类的使用方法学习笔记【附getID3源码下载】
2019/10/18 PHP
Avengerls vs KG BO3 第一场2.18
2021/03/10 DOTA
获取页面高度,窗口高度,滚动条高度等参数值getPageSize,getPageScroll
2006/09/22 Javascript
jQuery实现可收缩展开的级联菜单实例代码
2013/11/27 Javascript
jQuery实现输入框下拉列表树插件特效代码分享
2015/08/27 Javascript
javascript数组克隆简单实现方法
2015/12/16 Javascript
JS异步加载的三种实现方式
2017/03/16 Javascript
JavaScript中清空数组的三种方式
2017/03/22 Javascript
Vue配合iView实现省市二级联动的示例代码
2018/07/27 Javascript
vue学习之Vue-Router用法实例分析
2020/01/06 Javascript
jquery向后台提交数组的代码分析
2020/02/20 jQuery
Node.js中文件系统fs模块的使用及常用接口
2020/03/06 Javascript
js实现简单的无缝轮播效果
2020/09/05 Javascript
[52:14]VG vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
python查看FTP是否能连接成功的方法
2015/07/30 Python
Python字符编码与函数的基本使用方法
2017/09/30 Python
python+pandas生成指定日期和重采样的方法
2018/04/11 Python
python实现简单http服务器功能
2018/09/17 Python
python实现事件驱动
2018/11/21 Python
dpn网络的pytorch实现方式
2020/01/14 Python
PyQt5 如何让界面和逻辑分离的方法
2020/03/24 Python
jupyter 实现notebook中显示完整的行和列
2020/04/09 Python
Python 带星号(* 或 **)的函数参数详解
2021/02/23 Python
css3利用transform变形结合事件完成扇形导航
2020/10/26 HTML / CSS
ProBikeKit美国官网:自行车套件,跑步和铁人三项套件
2016/10/13 全球购物
美体小铺英国官网:The Body Shop英国
2017/01/24 全球购物
Sixt美国租车:高端豪华车型自驾体验
2017/09/02 全球购物
新东网科技Java笔试题
2012/07/13 面试题
C语言开发工程师测试题
2016/12/20 面试题
会计出纳员的自我评价
2014/01/15 职场文书
房产委托公证书样本
2014/04/04 职场文书
蓝颜请假条
2014/04/11 职场文书