WebSocket + Redis简单快速实现Web网站单设备登录功能

简介: 单设备登录作用很明显,就是为了保护用户账号安全,今天我们不说手机APP,我们来说说PC Web网站如何简单快速实现这种效果。本篇文章重点是实现单设备登录,内容未涉及WebSocket + Redis的概念和使用方法。限于本人经验,如有错误,欢迎指正。

1、写在前面的话

生活中,我们在使用一些APP的时候,有过一种体验,就是在A手机上登录账号,因为某些原因需要在B手机上登录,然后就会在A手机上看到类似"该账号在其他设备登录"的提示,像下面这样:

image.png

这种方式叫单设备登录,作用很明显,就是为了保护用户账号安全,今天我们不说手机APP,我们来说说PC Web网站如何简单快速实现这种效果。本篇文章重点是实现单设备登录,内容未涉及WebSocket + Redis的概念和使用方法。限于本人经验,如有错误,欢迎指正。

image.png

2、概念

简单的给”单设备登录“定义一下,就是只能在一个设备上登录,若同时在其他设备登录,先前登录的用户会被提醒:该账户在其他设备登录。例如微信,在一台手机登录中,同时拿另一台手机登录该账户,之前那部手机的账户会被挤下线。

image.png

3、思路

使用此方案的前提是要保证登录账号没有重复

在socket里面创建两个Map,sessionPool和sessionIds,分别用来存放客户端会话池和客户端会话标记

用户登录账号成功,进入应用首页,和服务端建立socket连接,将账号+"_"+UUID格式的字符串作为state参数的值

在OnOpen连接时,以state为key,当前session为value存入sessionPool,以sessionId为key,state为value存入sessionIds

以"_"分隔state成数组,取第一个元素即获取到当前登录的账号

在缓存(Redis)里模糊查询含有该账号的key集合,如果存在,那么就取出对应的value值,其实这个value存的就是首先登陆这个账号的那个state,就可以根据这个state给先登录的账号设备推送消息并做logout的操作,并清除缓存

把当前登录的state作为key和value存入缓存,失效时间设置与否都可以,如果设置的话需超过登录态失效的时长

image.png

4、代码实现

这里贴上几段核心代码

后台WebSocket-On0pen,切记如果设置缓存失效时间的话需超过登录态失效的时长

 * 连接时触发
 * @param state
 * @param session
 */
@OnOpen
public void onOpen(@PathParam(value = "state")String state,Session session) {
    this.session = session;
    sessionPool.put(state, session);
    sessionIds.put(session.getId(), state);     
    String[] arry = state.split("_");
    Set<String> keys = redisService.keys(arry[0] + "*");
    if (keys != null) {
        List<String> list = redisService.multiGet(keys);
        for (String value : list) {
            sendMessage("您的账号于"+ DateUtils.pageformat(DateUtils.getCurrentTime()) + "在另一台设备登录,如果这不是您的操作,那么您的登录密码已泄露,请尽快修改",value);
            redisService.delete(value);
        }
    }
    redisService.set(state,state,7200);
}

/**
 * 自定义发送消息的方法
 * @param message
 * @param state
 */
public static void sendMessage(String message,String state) {
    Session session = sessionPool.get(state);
    if (session != null) {
        try {
            session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

查看缓存

image.png

前端js连接WebSocket方法

return 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    var r = Math.random() * 16 | 0,
        v = (c === 'x' ? r : (r & 0x3 | 0x8));
    return v.toString(16);
});
}

function loginSocket(userName) {
var websocket = null;
if ('WebSocket' in window) {
    websocket = new WebSocket("ws://localhost:8080/mobile/socketServer/"+userName+"_"+getUUID());
} else {
    layer.alert('当前浏览器 不支持 websocket')
}
//连接成功建立的回调方法
websocket.onopen = function () {
    console.log('websocket连接成功');
};
//连接发生错误的回调方法
websocket.onerror = function () {
    console.log('websocket连接发生错误');
};
//接收到消息的回调方法
websocket.onmessage = function (event) {
    $.getJSON("logout", function(r){
        console.log('logout:'+event.data);
    });
    layer.confirm(event.data, {
        btn: ['确定'] //按钮
    }, function(){
        location.href = 'login.html';
    });
};
//连接关闭的回调方法
websocket.onclose = function () {
    console.log("websocket连接关闭");
};
//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function () {
    websocket.close();
};
}

image.png

5、验证效果

打开谷歌浏览器,账号密码登录

打开火狐浏览器,模拟不同设备,账号密码登录

再看下谷歌浏览器,页面弹窗提示

image.png

点击确定会跳转到登录页,谷歌浏览器的账号已经被挤下线退出应用

谷歌浏览器再次登录,看下火狐浏览器,也弹窗提示,之前登录的账号也被挤下线退出应用

image.png

山水有相逢,来日皆可期,谢谢阅读,我们再会

我手中的金箍棒,上能通天,下能探海

上一篇:Linux安装Elasticsearch

相关文章
|
JavaScript Java 微服务
现代化 Java Web 在线商城项目技术方案与实战开发流程及核心功能实现详解
本项目基于Spring Boot 3与Vue 3构建现代化在线商城系统,采用微服务架构,整合Spring Cloud、Redis、MySQL等技术,涵盖用户认证、商品管理、购物车功能,并支持Docker容器化部署与Kubernetes编排。提供完整CI/CD流程,助力高效开发与扩展。
1205 64
|
11月前
|
存储 NoSQL 前端开发
Redis专题-实战篇一-基于Session和Redis实现登录业务
本项目基于SpringBoot实现黑马点评系统,涵盖Session与Redis两种登录方案。通过验证码登录、用户信息存储、拦截器校验等流程,解决集群环境下Session不共享问题,采用Redis替代Session实现数据共享与自动续期,提升系统可扩展性与安全性。
619 3
Redis专题-实战篇一-基于Session和Redis实现登录业务
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
707 4
|
开发者
(WEB CAD online )在线CAD实现圆孔标记功能
本文介绍了通过自定义实体 `McDbTestRoundHoleMark` 实现圆孔标记功能的方法。该功能支持多象限标记、可调节标记角度、多重标记及动态编辑,并自动计算包围盒以优化空间定位与选择操作。核心实现包括类结构定义、数据序列化、标记数据设置、夹点编辑及实体绘制等步骤。用户可通过插件初始化注册并创建圆孔标记,适用于工程图纸标注场景。在线Demo展示了实际效果,便于开发者参考与使用。
基于springboot+thymeleaf+Redis仿知乎网站问答项目源码
基于springboot+thymeleaf+Redis仿知乎网站问答项目源码
455 36
|
监控 Linux PHP
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
630 20
|
Web App开发 前端开发 JavaScript
Web开发者必收藏的10个实用网站,你还没收藏吗?
将这些网站收藏起来,定期访问,使它们成为您日常工作的一部分,助您在快速发展的 Web 开发领域保持领先。
919 2
Web开发者必收藏的10个实用网站,你还没收藏吗?
|
安全 大数据 数据挖掘
课时9:阿里云Web应用防火墙:全面保障网站的安全与可用性
阿里云Web应用防火墙(WAF)基于阿里巴巴十年攻防经验,提供全面的网站安全防护。它通过Web应用防护、CC攻击防护和业务风控,有效应对各类网络威胁,确保网站的安全与可用性。智能双引擎技术降低误报率,实时数据分析和虚拟补丁更新保障系统安全。WAF已成功护航多个重大活动,为企业提供高效、简便的安全解决方案。
574 0
|
监控 关系型数据库 MySQL
【01】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-硬件设备实时监控系统运营版发布-本产品基于企业级开源项目Zabbix深度二开-分步骤实现预计10篇合集-自营版
【01】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-硬件设备实时监控系统运营版发布-本产品基于企业级开源项目Zabbix深度二开-分步骤实现预计10篇合集-自营版
711 0
|
Web App开发 网络协议 安全
基于Web攻击的方式发现并攻击物联网设备介绍
基于Web攻击的方式发现并攻击物联网设备介绍
358 4