实现简易的扫码登录(附Demo)

如何实现简易的扫码登录

大家好,我是梦辛工作室的灵,话说又是好久没有更新了,但这绝对不是因为楼主懒=-=,真哒真哒,好吧,假期太长了主要,然后就越耍越皮了=-=,不扯了,那进入今天的正题,如何实现 扫码登录,我这边画好了一个 简易的原理图便于 大家更好的理解:
在这里插入图片描述
显示由客户端 产生一个 带有指向登录地址并含有唯一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  随机注册一个id
               var 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()
               { 
                  // 关闭 websocket
                  console.log("连接已关闭..."); 
               };

               draw("http://127.0.0.1:8080/login.html?id=" + id,"content");
            }
            
            else
            {
               // 浏览器不支持 WebSocket
               alert("您的浏览器不支持 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(){ 
		          // 关闭 websocket
		          console.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
	 */
	@OnOpen
	public 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
	 */
	@OnClose
	public void onClose(Session session) throws IOException {
		// 关闭session
		if (id == null) {
			return;
		}
		WsServerManager.removeWsServer(id); // 从set中删除
		System.out.println("设备 " + id + " 连接关闭!当前在线设备为" + getOnlineCount());
	}

	public void Close() throws IOException {
		// 关闭session
		if (session != null && session.isOpen()) {
			session.close();
		}
	}

	/**
	 * 收到客户端消息后调用的方法
	 * 
	 * @param message
	 *            客户端发送过来的消息
	 * @param session
	 *            可选的参数
	 */
	@OnMessage
	public 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
	 */
	@OnError
	public 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);
	}
}

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

发布了36 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_41392105/article/details/104265226