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

相关文章
|
11月前
|
存储 NoSQL 前端开发
Redis专题-实战篇一-基于Session和Redis实现登录业务
本项目基于SpringBoot实现黑马点评系统,涵盖Session与Redis两种登录方案。通过验证码登录、用户信息存储、拦截器校验等流程,解决集群环境下Session不共享问题,采用Redis替代Session实现数据共享与自动续期,提升系统可扩展性与安全性。
592 3
Redis专题-实战篇一-基于Session和Redis实现登录业务
|
前端开发 JavaScript UED
探索Python Django中的WebSocket集成:为前后端分离应用添加实时通信功能
通过在Django项目中集成Channels和WebSocket,我们能够为前后端分离的应用添加实时通信功能,实现诸如在线聊天、实时数据更新等交互式场景。这不仅增强了应用的功能性,也提升了用户体验。随着实时Web应用的日益普及,掌握Django Channels和WebSocket的集成将为开发者开启新的可能性,推动Web应用的发展迈向更高层次的实时性和交互性。
449 1
|
监控 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
617 20
|
JSON 自然语言处理 前端开发
WebSocket调试工具深度对比:Postman与Apipost功能实测解析
本文深入对比了Postman与Apipost两款WebSocket调试工具。作为实时通讯系统工程师,作者在开发智能客服系统时遇到了传统工具调试复杂、文档管理不便的问题。通过引入Apipost的智能连接池、消息分组管理和自动化文档生成等功能,实现了多环境自动切换、消息分类和接口文档自动生成,极大提升了调试效率和团队协作效果。最终,使用Apipost使接口调试时间减少40%,文档维护成本降低70%,跨团队沟通效率提升50%。
|
JSON 前端开发 安全
WebSocket调试工具深度对比:Postman与Apipost功能实测解析
如果你在寻找既能搞定WebSocket调试,又能完美管理文档的工具,不妨试试Apipos!
682 1
|
弹性计算 JSON 自然语言处理
语音交互产品通过WebSocket协议对外提供实时语音流语音转写功能
阿里云智能语音交互产品通过WebSocket协议提供实时语音转写功能,支持长语音。音频流以Binary Frame上传,指令和事件为Text Frame。支持单声道、16 bit采样位数的PCM、WAV等格式,采样率8000Hz/16000Hz。可设置返回中间结果、添加标点、中文数字转阿拉伯数字,并支持多语言识别。服务端通过临时Token鉴权,提供外网和上海ECS内网访问URL。交互流程包括StartTranscription、StopTranscription指令及多种事件反馈。
1205 15
|
安全 大数据 数据挖掘
课时9:阿里云Web应用防火墙:全面保障网站的安全与可用性
阿里云Web应用防火墙(WAF)基于阿里巴巴十年攻防经验,提供全面的网站安全防护。它通过Web应用防护、CC攻击防护和业务风控,有效应对各类网络威胁,确保网站的安全与可用性。智能双引擎技术降低误报率,实时数据分析和虚拟补丁更新保障系统安全。WAF已成功护航多个重大活动,为企业提供高效、简便的安全解决方案。
552 0
|
Web App开发 前端开发 JavaScript
Web开发者必收藏的10个实用网站,你还没收藏吗?
将这些网站收藏起来,定期访问,使它们成为您日常工作的一部分,助您在快速发展的 Web 开发领域保持领先。
852 2
Web开发者必收藏的10个实用网站,你还没收藏吗?
|
监控 关系型数据库 MySQL
【01】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-硬件设备实时监控系统运营版发布-本产品基于企业级开源项目Zabbix深度二开-分步骤实现预计10篇合集-自营版
【01】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-硬件设备实时监控系统运营版发布-本产品基于企业级开源项目Zabbix深度二开-分步骤实现预计10篇合集-自营版
687 0
|
Web App开发 网络协议 安全
基于Web攻击的方式发现并攻击物联网设备介绍
基于Web攻击的方式发现并攻击物联网设备介绍
340 4

热门文章

最新文章