《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
高认可度评论:
你要的是不是这个?
什么叫避免重复登录,如果是登录过一次之后就不再输入密码的话, Laravel 已经自带 “记住我”的功能了。
@SZL_ 可以用这个 用户认证《Laravel 5.8 中文文档》
你要的是不是这个?
其实你说的就是唯一登陆,实现起来不难
那这个要怎么用@kangfq

涉及概念:
实现方案:
Redis
当中并设置有效期(例如:设置30
分钟)。Redis
是否已经存在状态,如果存在则不让其登录。总结:
简单点 用户名当键 登录时间戳为值 存起来 每次请求携带登陆时间戳,验证这个登陆时间戳是否和当前用户的登陆时间戳一样
(该方法比较原始,但思路比较明确,可能存有思考不当地方,可以自己加以修改)
'-------------------------------------------------------'分割线
比如user现在登陆了 ,缓存用redis。
那么redis::set('user','2019-08-29 10:54:00(你可以存时间戳)','3600(一小时)')。
然后session('user','2019-08-29 10:54:00(你可以存时间戳)')
比如现在user来请求了。那好,你通过user取得session和redis里的登陆时间,然后判断是否一致。
如果一致,那好,说明没有别人更新这个缓存,也就没人用user第二次登陆。
如果redis过期了,也就是一小时到了,此时session确还有效,在续命一个小时就可以了,如果session过期了,直接退出,清空redis缓存。
如果没过期情况下第二个人也用这个user登陆了,那么按照逻辑,
他也会session('user',''2019-08-29 11:24:00(你可以存时间戳)'),redis::set('user','2019-08-29 11:24:00(你可以存时间戳)','3600(一小时)'),此时redis的值被改变了。
按照redis是共享的,所以此时这个redis里的登陆时间就变掉了。那么第一个user过来请求,此时他的session里的登陆时间就和redis里的登陆时间不一样了。因为被第二个user更新了。
如果你不想让第二个人登陆,就在每次登陆时检查redis里是否存在这个user的缓存。
为了保证缓存利用性,要给缓存设置过期时间,和退出清空缓存,请求是发现session过期了,退出登陆时也要清空缓存。
然后上面也说了,缓存过期时间快过session过期,给缓存续命就好了,续命的前提是缓存不存在,而不是缓存存在但登陆时间不同。
类似QQ挤下线操作吧, 当时是做的APP, 用的是设备号做唯一凭证
看你应用的场景了,APP 的话保证 TOKEN 唯一,一端登录 TOKEN 改变,TOKEN 失效,PC 端基于SESSION 的话那就是 session 失效
避免同时登录的情况有两种
这种情况比较好处理,只要登录的时候重置下token,那么之前登录状态的账号就失效了
这种情况下,你只要在用户表增加一个登录状态的字段,每次登录之前,判断这个字段是否为登录状态即可
我的做法(apitoken 方式)

创建中间表模型
登录的时候调用
createToken
所有请求中间件调用
hasToken
简单方式:直接记录在cache()缓存中,以用户id为键,以到期时间为值,每次访问更新到期时间,有值说明已经登录过,没有值则是未登录
最简单的方法是用户登录成功后把用户的sessionId储存到缓存中,然后再cookie中也存一份sessionId,用户访问的时候,比较这两个sessionId,如果不一样,那就踢下线
直接点 用token方式 如果当前请求接口的token跟uid不一样那么就是不是同一个人了
我的实现原理:使用浏览器的
session id
来判断,每次用户登录后更新用户的session id
,然后通过中间件来过滤,不知道是不是你想要的效果,这是 5.5 的版本,5.5 以上版本好像自带有这种功能。中间件
app/Http/Middleware/SingleDeviceLogin.php
app/Http/Kernel.php
中$middlewareGroups
的web
中登录事件
app/Listeners/LoginListener.php
app/Providers/EventServiceProvider.php
注册监听事件至此,完成
实现避免账户同时登录,核心就是用一张表记录用户会话信息。
用户会话表:会话ID、用户ID、登录状态(已登录、已退出)
当用户在新设备身份验证成功登录时,会产生新会话,登录状态为已登录;同时根据会话记录,将该用户历史的会话记录登录状态从已登录标记为已退出即可。
另一方面,用户登录态检查的中间件,要求登录状态为已登录。
用这个办法可以实现。
https://www.jianshu.com/p/a8cf3a481b11
常见的无外乎两种场景。
1.基于cookie+session的用户认证
不管先后登陆成功--->都保存session_id(可以在用户表加一个字段保存or存在redis里)
中间件校验session_id和服务器保存的session_id是否一致。不一致(被挤掉了)销销毁该会话session跳转到登录页。
原理就是后者登录成功会把保存的session_id更新。
2.基于token的用户认证,后者登录成功直接重置token即可。
登录成功后把密码重新bcrypt一下并更新到users表,然后把新加密好的密码存入session。
中间件验证登录的用户session里面的密码和users表里面的是否相同,如果不同的话就退出这个用户的登录,官方的好像也是这么实现的。