如何实现简易的扫码登录

大家好,我是梦辛工作室的灵,话说又是好久没有更新了,但这绝对不是因为楼主懒=-=,真哒真哒,好吧,假期太长了主要,然后就越耍越皮了=-=,不扯了,那进入今天的正题,如何实现 扫码登录,我这边画好了一个 简易的原理图便于 大家更好的理解:

显示由客户端 产生一个 带有指向登录地址并含有唯一ID的二维码,并与服务端保持长连接,楼主这里 为了方便直接使用的 ws 协议,你也可以使用 tcp协议来实现,这样就在服务端有了一个 待登录的客户端长连接,然后 用户扫码时 会获取到 该id 并且连接服务端 向生成二维码的客服端 发送 扫扫码成功通知,然后生成二维码的客户端刷新UI,显示 扫码成功,用户在 手机扫码成功的界面 点击确认登录,或输入账号密码登录,传给服务器,服务器 通过读取数据库验证密码通过后,将用户相关信息 发送给 客户端,这样就完成 扫码登录了,还是挺简单的吧,下面直接来看代码:
首先是 客户端:

<!DOCTYPE HTML>
<html><head><meta charset="utf-8"><title>扫码登录实现Demo</title><script type="text/javascript" src="qrcode.min.js"></script><script type="text/javascript">window.onload = function(res){if ("WebSocket" in window){  // 打开一个 web socket  随机注册一个idvar id = createId(10);var ws = new WebSocket("ws://localhost:8080/websocket?openid="  + id );ws.onopen = function(){// Web Socket 已连接上,使用 send() 方法发送数据console.log("成功建立连接");};ws.onmessage = function (evt) { var received_msg = evt.data;console.log("接收到数据:"  + received_msg);try{var jsonData = JSON.parse(received_msg);if (jsonData.account && jsonData.password) {alert("账号 " + jsonData.account + " 登录成功");} if(jsonData.scan){document.getElementById("success_div").style.display = "flex";}}catch(e){}};ws.onclose = function(){ // 关闭 websocketconsole.log("连接已关闭..."); };draw("http://127.0.0.1:8080/login.html?id=" + id,"content");}else{// 浏览器不支持 WebSocketalert("您的浏览器不支持 WebSocket!");}}function createId(len){var baseStr = "0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM" + (new Date()).getTime();var randStr = "";for(var i = 0; i < len; i++){randStr += baseStr[Math.floor(Math.random() * baseStr.length)];}return randStr;}function draw(text,id) { var qrcode = new QRCode(document.getElementById(id), {width : 200,height : 200});qrcode.makeCode(text);}</script></head><body><div id="content" style="width: 100vw;height: 60vh;display: flex;flex-direction: column;justify-content: center;align-items: center;"><div id="success_div" style="width: 200px;height: 200px;position: absolute;z-index: 1;background: rgba(0,0,0,0.5);display: none;flex-direction: column;justify-content: center;align-items: center;"><img src="ic_success.png" width="50" height="50"><span style="font-size: 90%;color: #ffffff;margin-top: 5px;">扫码成功</span></div></div></body>
</html>

界面显示的话实质上就是一个 二维码,然后就没有了:

接下来就是 手机 扫码时的界面和代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>登录</title>
</head>
<script type="text/javascript">var id = "";var reqId  = "";var ws = {};window.onload = function(){var param = window.location.search;if (param.length > 0) {param = param.substring(1);param = param.split("=");id = param[1];reqId = createId(10);ws = new WebSocket("ws://localhost:8080/websocket?openid="  + reqId );ws.onopen = function() {// Web Socket 已连接上,使用 send() 方法发送数据console.log("成功建立连接");var message = {sendid:id,id:reqId,scan:1};ws.send(JSON.stringify(message));};ws.onmessage = function (evt) { var received_msg = evt.data; };ws.onclose = function(){ // 关闭 websocketconsole.log("连接已关闭..."); }} else {alert("错误的ID");}}function login(argument) {console.log("调用登录");var account = document.getElementById("account").value;if(account.length == 0){alert("账号不能为空");}var password = document.getElementById("password").value;if(password.length == 0){alert("密码不能为空");}var message = {sendid:id,id:reqId,account,password};ws.send(JSON.stringify(message));return false;}function createId(len){var baseStr = "0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM" + (new Date()).getTime();var randStr = "";for(var i = 0; i < len; i++){randStr += baseStr[Math.floor(Math.random() * baseStr.length)];}return randStr;}</script>
<body style="width: 100vw;height: 100vh;display: flex;justify-content: center;align-items: center;"><div   >账号: <input type="text"  id="account" value="" placeholder="请输入账号"><br>密码: <input type="text" id="password" value="" placeholder="请输入密码" style="margin-top: 10px"><br><input onclick="login()" type="button" value="提交" style="margin-top: 10px"></div> </body>
</html>


这里面楼主没有加加密操作,对于信息较为隐秘的请加密,最后放上服务端的代码:

package com.px.wsserver;import java.io.IOException;import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;import net.sf.json.JSONObject;@ServerEndpoint("/websocket")
public class WsServer {// 与某个客户端的连接会话,需要通过它来给客户端发送数据private Session session;private String id;private StringBuffer caheData = new StringBuffer();public WsServer() {System.out.println("-----------------------------");}/*** 连接建立成功调用的方法* * @param session*            可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据* @throws IOException*/@OnOpenpublic void onOpen(Session session) throws IOException {this.session = session;String url = session.getRequestURI().toString();int usernameindex = url.indexOf("username=");int pwdindex = url.indexOf("&pwd=");int openidindex = url.indexOf("openid=");if (usernameindex >= 0 && pwdindex >= 0) {String username = url.substring(usernameindex + "username=".length(), pwdindex);String pwd = url.substring(pwdindex + "&pwd=".length());if (!username.equalsIgnoreCase("admin") || !pwd.equalsIgnoreCase("123456")) {sendMessage("未知用户");System.out.println("错误用户,断开连接:" + url);this.Close();return;}id = username + pwd;if (WsServerManager.existServer(id)) {sendMessage("该id已连接,请勿重复连接");System.out.println(id + "已连接,请勿重复连接,断开连接");id = null;this.Close();return;}WsServerManager.addWsServer(id, this); // 加入set中System.out.println("设备  " + id + " 加入!当前在线设备为" + getOnlineCount());} else if (openidindex >= 0) {String openid = url.substring(openidindex + "openid=".length());id = openid;if (WsServerManager.existServer(id)) {sendMessage("该id已连接,请勿重复连接");System.out.println(id + "已连接,请勿重复连接,断开连接");id = null;this.Close();return;}WsServerManager.addWsServer(id, this); // 加入set中System.out.println("设备  " + id + " 加入!当前在线设备为" + getOnlineCount());} else {sendMessage("缺少必要参数");id = null;this.Close();return;}}/*** 连接关闭调用的方法* * @throws IOException*/@OnClosepublic void onClose(Session session) throws IOException {// 关闭sessionif (id == null) {return;}WsServerManager.removeWsServer(id); // 从set中删除System.out.println("设备 " + id + " 连接关闭!当前在线设备为" + getOnlineCount());}public void Close() throws IOException {// 关闭sessionif (session != null && session.isOpen()) {session.close();}}/*** 收到客户端消息后调用的方法* * @param message*            客户端发送过来的消息* @param session*            可选的参数*/@OnMessagepublic void onMessage(String message, Session session) {System.out.println("接收  " + id + " 的消息:" + message);try {JSONObject jsonObject = JSONObject.fromObject(message);String sendid = jsonObject.getString("sendid");if (sendid != null && sendid.length() > 0) {WsServer wsserver = WsServerManager.getWsServer(sendid);if (wsserver == null) {System.out.println(sendid + " 未连接");return;}wsserver.sendMessage(jsonObject.toString());}} catch (Exception e) {e.printStackTrace();} }/*** 发生错误时调用* * @param session* @param error*/@OnErrorpublic void onError(Session session, Throwable error) {System.out.println("发生错误");error.printStackTrace();}/*** * * @param message* @throws IOException*/public void sendMessage(String message) throws IOException {this.session.getBasicRemote().sendText(message);}public static synchronized int getOnlineCount() {return WsServerManager.getCount();}}
package com.px.wsserver;import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; public class WsServerManager {private static ConcurrentMap<String,WsServer> webSocketSet = new ConcurrentHashMap<String, WsServer>();private static ConcurrentMap<String,DevInfo> MacDataMap = new ConcurrentHashMap<String, DevInfo>();public static void addWsServer(String id,WsServer server) {webSocketSet.put(id, server);}public static void addDevInfo(String mac,String Data) {DevInfo devInfo = MacDataMap.get(mac);if (devInfo == null) {devInfo = new DevInfo();} devInfo.setMac(mac);devInfo.setOnline_data(Data);MacDataMap.put(mac, devInfo);}public static DevInfo getDevInfo(String mac) {return MacDataMap.get(mac);}public static WsServer getWsServer(String id) {return webSocketSet.get(id);}public static boolean removeWsServer(String id) throws IOException { if (webSocketSet.get(id) == null) {return false;}WsServer wsServer = webSocketSet.remove(id);wsServer.Close();return true;}public static int getCount() {return webSocketSet.size();}public static boolean existServer(String id) {return webSocketSet.containsKey(id);}
}

大家有什么问题或有什么更好的建议都已评论出来,一起共同进步

实现简易的扫码登录(附Demo)相关推荐

  1. Java 语言实现简易版扫码登录

    基本介绍 相信大家对二维码都不陌生,生活中到处充斥着扫码登录的场景,如登录网页版微信.支付宝等.最近学习了一下扫码登录的原理,感觉蛮有趣的,于是自己实现了一个简易版扫码登录的 Demo,以此记录一下学 ...

  2. SpringBoot实现扫码登录

    文章目录 一.概述 1.扫码登录介绍 2.扫码登录原理 二.扫码登录实战(轮询版) 1.环境准备 2.RedisTemplate序列化 3.Token工具类 4.定义扫码状态 5.定义返回类 6.定义 ...

  3. 手机二维码扫码登录(Java源码及思路)

    QRCodeLogin 二维码扫码登录:服务器端.网页端.移动端源码: 项目介绍 一个二维码扫码登录的demo,能够完整的实现用户扫码登录的过程,源码地址. 项目一共包含三分源码:服务器端.网页端和移 ...

  4. 二维码扫码登录详解【附简易实例代码(html+php+ios)】

    1.前言 我们在写一个不太了解的新功能的时候,又稳又快的一个方法就是借(chao)鉴(xi)其他的人的实现方法.所以我们先不急着开始写代码,先看一下各互联网巨头都是如何实现的. 首先来看一下淘宝的扫码 ...

  5. Spring学习笔记(二十三)——实现网站微信扫码登录获取微信用户信息Demo

    目录 微信扫码登录介绍 开发步骤 微信扫码登录示例 微信开放文档 遇到的问题 使用第三方工具实现网站微信扫码登录 开发前介绍 开发步骤 微信扫码登录获取微信用户信息Demo实现流程 实现效果 实现过程 ...

  6. 个人博客网站实现微信扫码登录(附源码)

    前言 一般情况下,个人博客网站 想要做用户注册.登录, 就需要让用户填写用户名.密码等信息进行手动注册.登录,这非常不友好.如果想做成微信扫码登录,对不起~~, 微信扫码登录的接口只对企业开放.好吧, ...

  7. 一文搞懂主流的扫码登录技术原理(附源码)

    点击上方[全栈开发者社区]→右上角[...]→[设为星标⭐] 1.引言 扫码登录这个功能,最早应该是微信的PC端开始搞,虽然有点反人类的功能(不扫码也没别的方式登录),但不得不说还是很酷的. 下面这张 ...

  8. 微信扫码登录实战(附代码)

    来源:JAVA葵花宝典 导读:由于微信端流量比较足,所以扫码登录系统功能也受到了很多系统的青睐,本文就来详细的解开该技术的面纱. 演示效果 准备工作 1. 需要一个微信开放平台账号,并创建一个网站应用 ...

  9. Spring Boot 实现扫码登录,太赞了(附源码)!!

    点击上方[全栈开发者社区]→右上角[...]→[设为星标⭐ 点击领取全栈资料:全栈资料 一.首先咱们需要一张表 二.角色都有哪些 三.接口都需要哪些? 四.步骤 五.疯狂贴代码 springBoot中 ...

最新文章

  1. mysql数据库入门题型_mysql数据库入门
  2. 没学过python、但是还是有公司要-想转行,是要入坑Python还是Java?这问题还用问?...
  3. java面试题2(java基础)
  4. C/C++ 回调函数是什么?Intel Realsense里的回调(callback)是什么?
  5. springboot整合postgre和hbase实现互相交互功能
  6. 计算机图形与游戏技术,宾夕法尼亚大学计算机图形与游戏技术研究生Offer及录取要求...
  7. 正则表达式入门之字符匹配
  8. hive sqoop 分区导入_利用oozie,执行sqoop action将DB2中的数据导入到hive分区表中
  9. “~/” 代表应用程序根目录的一点误区
  10. 芜湖市计算机应用能力考试,安徽省芜湖市2021年3月计算机等级考试时间
  11. 2.7 if应用:猜拳游戏
  12. 变更DirectX SDK版本-DirectX8升级DirectX9
  13. 盘点:QuickTime Player 键盘快捷键和手势大全
  14. mfc 中文乱码转换为正常中文_MFC下遇到的字符集和中文乱码问题
  15. KEIL MDK 查看代码量、RAM使用情况--Code、RO-data、RW-data、ZI-data的解释
  16. canvas使用硬件加速
  17. 抓住元宇宙的劲风,谁在点燃虚拟经济?
  18. 采用以太坊智能合约技术的报名系统源码
  19. 黑苹果oc清除nvram_基于OpenCore0.6.1的黑苹果安装,小白也能看
  20. 聊聊benchmark测试

热门文章

  1. 分享几款小白从零开始学习的会用到的工具/网站
  2. 《python初级爬虫》(二)
  3. 程序员如何晋升项目经理?
  4. 座头鲸识别比赛(Humpback Whale Identification)总结
  5. L3-020 至多删三个字符 (30 分)(DP)
  6. Java 从零开始学爬虫(gecco)
  7. 内网渗透(十)之内网信息收集-编写自动化脚本收集本地信息
  8. 华为鸿蒙电视,开卖40天,搭载鸿蒙OS操作系统的华为电视就差评如潮?用户:亏了...
  9. 萌新学Java之渐入佳境一----初识多线程
  10. excel处理几十万行数据_Excel处理数万条数据很慢,怎么办?