文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Web-解决同一账号多处登录的问题

2023-09-04 09:10

关注

  如果用户通过同一账号在不同浏览器甚至不同ip登录会对账号安全,数据逻辑处理产生巨大隐患,这里介绍几种常见的解决办法:

1.MySql数据库设置登录状态

实现:

         在account表中添加字段'isLogin'

        登录时,更新为true

        退出时,更新为false

当登录时查询该字段,如果为true,就表明该账号已登录,阻止这次登录

缺点:

解决办法:

        但是如果我们设置的间隔时间太短,上一个用户还没退出,下一个用户就开始登录,因为我们设置了loginTime,第二个用户也可以成功登录账号,这就又绕回来了,根本没有解决问题

        如果我们设置的间隔时间过长,用户非正常退出后,如果想重新登录就得等待完这个间隔时间,比如很多网站账号登录的安全最效时间是30分钟,如果不小心退出来,则至多要等30分钟,对用户简直是种折磨

        这就引入第二种解决办法

2.数据库的临时表

        mysql中是支持临时表的,临时表顾名思义,就是使用时创建,关闭时自动删除的一种表,一般有着缓存数据,提高数据提取效率的功能

实现:

        连接数据库时(即登录成功时)创建一个临时表,将账号等信息写进去

        登录时检查对应账号的临时表是否存在,如果是,就证明有用户已经登录,阻止这次登录,没有则允许登录

        重点来了:临时表的生存是由是否连接数据库决定的,当断开数据库的连接时,临时表会自动删除,这就解决了第一个方法产生的问题,当用户非正常退出时,也就意味着数据库的断开,直接实现了用户退出即清空数据的需求

缺点:

3.令牌Token的使用

实现:

        在登录时创建一个随机值token,写入对应账号的字段'token'中,并将该值返回前端,当每次调用get或post方法时,将token随数据一起提交

        提交后,后端比对该值是否与字段'token'的值是否相同,相同则继续执行下面的代码...不相同就证明有另一个用户登录该账号了

缺点:

解决办法:

以上的方法是网上常见但无法根本解决该文章提出的问题或性能开支巨大的方案,这里提供一个不成熟的方案

最终的解决办法:

4.公钥和私钥的使用

实现:

        在数据库账号表中增加一个字段‘privateKey’来储存私钥

        用户登录成功后,后端生成一个新的公钥和私钥,将私钥储存在session中(这里可能有人会问,同一个浏览器多开窗口session不是会共用吗?不要着急,一会会解释),将公钥返回前端。

 "sha512",    "private_key_bits" => 4096,               "private_key_type" => OPENSSL_KEYTYPE_RSA,);$res = openssl_pkey_new($config); //提取私钥openssl_pkey_export($res, $private_key); //生成公钥$public_key = openssl_pkey_get_details($res);$public_key = $public_key["key"];session_start();//保存私钥到session中$_SESSION['privateKey'] = $private_key;//返回公钥exit($public_key);

        在前端中,所有提交的数据都采用该公钥加密

var publicKey;//获取后端生成的公钥$.ajax({    url:'getPublicKey.php',    dataType:'json',    async:false,     success:function(response){        publicKey = response['publicKey'];        if(!publicKey){            console.log('获取失败');        }    }})//创建加密对象var encryptor = new JSEncrypt()//设置公钥encryptor.setPublicKey(publicKey)//对数据加密后发送$.ajax({    url:'../postData.php',    type:'post',    dataType:'json',    data:encryptor.encrypt('你要发送的数据'),//对发送的数据进行加密    success:function(){        ...    }

          在后端中,利用session保存下的私钥解密

        当其他用户登录时,会更新session和数据库对应账号的私钥privateKey,更新之后,第一个用户加密后的数据肯定是用当前的私钥解密不了的(一般情况下会返回空值),如果解密失败了,就证明私钥和公钥不对应,说明有另外的用户登录了,将此用户踢出即可

        在上面的代码中添加

if(!$content){    exit('已有其他用户登录,你无法对该账号进行操作');    //进行踢出用户等操作...}

优点:

  • 登录后不用每次请求都连接数据库来判断是否有其他用户登录,对数据库性能要求低
  • 采用了RSA加密,即使没有SSL,也保证了数据的安全
  • 只需在前端写一个加密方法,在后端写解密方法,不用单独为每个请求设置token,对前端和后端极其友好

缺点:

  • 每次都对数据进行加密解密,直接响应时间有所增加
  • rsa加密有可能无法加密过大文件
  • 后端返回的公钥有可能会被中途拦截,从而利用该公钥加密的数据进行提交

应对措施:

  • 牺牲数据安全性,采用对称加密,加密和解密速度会大大提升,但密钥使用非对称加密传输到前端
  • 将大文件分开传输(这不废话吗?哪有大文件不分开传的)
  • 在前端构建私钥和公钥,将公钥发送至后端,在后端用该公钥对后端生成的公钥加密后返回前端,在前端使用私钥解密

这种方案可以针对同一浏览器同时多开浏览页的情况,如果不想限制同一浏览器,在账号表中加入‘ip’字段,登录时检查该字段,具体实现不做解释了

该文章为作者原创,转载请获取作者同意

来源地址:https://blog.csdn.net/weixin_50338358/article/details/128843053

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯