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


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 相关文章推荐
跟着Jquery API学Jquery之一 选择器
Apr 07 Javascript
基于Jquery的文字滚动跑马灯插件(一个页面多个滚动区)
Jul 26 Javascript
javascript 弹出层组件(升级版)
May 12 Javascript
jquery+json实现数据二级联动的方法
Nov 28 Javascript
jQuery验证插件validate使用详解
May 11 Javascript
微信JS-SDK自定义分享功能实例详解【分享给朋友/分享到朋友圈】
Nov 25 Javascript
layer弹窗插件操作方法详解
May 19 Javascript
使用Node搭建reactSSR服务端渲染架构
Aug 30 Javascript
微信小程序实现获取准确的腾讯定位地址功能示例
Mar 27 Javascript
浅谈layer的Icon样式以及一些常用的layer窗口使用方法
Sep 11 Javascript
vue项目中使用particles实现粒子背景效果及遇到的坑(按钮没有点击响应)
Feb 11 Javascript
JavaScript TAB栏切换效果的示例
Nov 05 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
模仿OSO的论坛(二)
2006/10/09 PHP
php异常处理方法实例汇总
2015/06/24 PHP
CodeIgniter框架验证码类库文件与用法示例
2017/03/18 PHP
Yii2数据库操作常用方法小结
2017/05/04 PHP
php版本CKEditor 4和CKFinder安装及配置方法图文教程
2019/06/05 PHP
IE和Firefox下javascript的兼容写法小结
2008/12/10 Javascript
基于jquery+thickbox仿校内登录注册框
2010/06/07 Javascript
JQuery 选择器、过滤器介绍
2011/02/14 Javascript
jquery插件制作简单示例说明
2012/02/03 Javascript
Jquery选中或取消radio示例
2013/09/29 Javascript
JS方法调用括号的问题探讨
2014/01/24 Javascript
Ajax中解析Json的两种方法对比分析
2015/06/25 Javascript
利用JavaScript实现栈的数据结构示例代码
2017/08/02 Javascript
vue组件实现文字居中对齐的方法
2017/08/23 Javascript
Vue侧滑菜单组件——DrawerLayout
2017/12/18 Javascript
解决linux下node.js全局模块找不到的问题
2018/05/15 Javascript
JavaScript数据结构与算法之二叉树实现查找最小值、最大值、给定值算法示例
2019/03/01 Javascript
小程序登录之支付宝授权的实现示例
2019/12/13 Javascript
vue缓存之keep-alive的理解和应用详解
2020/11/02 Javascript
同时安装Python2 &amp; Python3 cmd下版本自由选择的方法
2017/12/09 Python
Python+selenium实现截图图片并保存截取的图片
2018/01/05 Python
使用matplotlib中scatter方法画散点图
2019/03/19 Python
Python 中pandas索引切片读取数据缺失数据处理问题
2019/10/09 Python
jupyter notebook实现显示行号
2020/04/13 Python
浅谈python3打包与拆包在函数的应用详解
2020/05/02 Python
django 解决扩展自带User表遇到的问题
2020/05/14 Python
ReVive利维肤美国官网:RéVive Skincare
2018/04/18 全球购物
大学军训感言1000字
2014/02/25 职场文书
纠风工作实施方案
2014/03/15 职场文书
幼儿园大班毕业教师寄语
2014/04/03 职场文书
大学生求职计划书
2014/04/30 职场文书
党员群众路线承诺书
2014/05/20 职场文书
学校春季防火方案
2014/06/08 职场文书
单位作风建设剖析材料
2014/10/11 职场文书
五星级酒店宣传口号
2015/12/25 职场文书
Java后端 Dubbo retries 超时重试机制的解决方案
2022/04/14 Java/Android