冻结用户业务总结

我们后台管理系统冻结用户发送请求携带userid

普通版本:

        1.通过userid我们可以作为Redis的key的一部分(最好携带前缀拼接便于看到key就明白内容)

        2.我们把用户冻结的信息(冻结原因、时间、备注、冻结的范围:例如冻结发言、冻结登录之类的)可以创建实体类、或者使用map集合吧数据存起来("使用map集合可以不用创建新的实体类,适用于字段比较少的时候、字段不确定时候")。

然后使用json工具类(例如fastjson)把map转成字符串然后使用springboot整合Redis的StringRedisTemplate,其中StringRedisTemplate和RedisTemplate的最大区别就是,存在StringRedisTemplate中的value是以string类型存储着,而RedisTemplate是会把对象序列化存储,如果使用StringRedisTemplate就取出value后可以再使用json转成map集合就方便许多。StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。

这里我是使用StringRedisTemplate

3.设置token有效期

        使用switch比if更直观,因为多条件判断,我们使用if会一直if..else..使我们的代码变得很杂乱,使用switch直观。而且到时候我们添加多新的冻结日期只需要多加一行即可

高级版本

        高级点的版本是我想到了,如果登录用户被冻结了登录,而我们需要的是userid来作为redis中的key一部分。所以我们每次登录时候,例如用户传进来手机号码、或者用户名来进行登录。我们还得帮他们查找数据库得到id才能进行Redis的校验是否被冻结?

这就导致了一些人可以使用for循环一直登录,即使被冻结了。还是会不断的刷我们数据库浪费性能。

所以我们可以使用用户名或者手机号来作为key的一部分可以防止这样的攻击。

代码:

        //1.获取用户id,得到手机号拼接前缀为key
        Integer userId = (Integer) map.get("userId");
        String phone=userApi.findUserPhoneByUserId(userId);
        String key="FreezeUser_"+phone;
        //2.获取用户冻结信息、冻结类型、冻结时间、冻结id(手机号)
        Integer freezingTime = Integer.valueOf(map.get("freezingTime").toString());
        String freezeInfo = JSON.toJSONString(map);
        //3.冻结用户,存到Redis中
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        switch (freezingTime){
                //冻结3天
            case 1: ops.set(key,freezeInfo,3, TimeUnit.DAYS);break;
                //冻结7天
            case 2: ops.set(key,freezeInfo,7, TimeUnit.DAYS);break;
                //永久冻结
            case 3: ops.set(key,freezeInfo);break;
            default:break;
        }
        Map<String,String> resultMap=new HashMap<>();
        resultMap.put("message",map.get("reasonsForFreezing").toString());
        //随便修改userinfo的数据库字段userStatus为2
        UserInfo userinfo = userInfoApi.findUserInfoById(userId.longValue());
        userinfo.setUserStatus("2");
        userInfoApi.save(userinfo);

我们举登陆页面为例子

        在我们登陆页面直接根据手机号判断是否符合要求即可

我们使用fastjosn转为map(这里使用parseObject(String text)得到JSONObject)

因为JSONObject本质也是个map

public class JSONObject extends JSON implements Map<String, Object>, Cloneable, Serializable, InvocationHandler
String phone = map.get("phone");
        //0.冻结判断
        String json = stringRedisTemplate.opsForValue().get("FreezeUser_" + phone);
        //判断是value否为null
        if(StringUtils.isNotEmpty(json)){
            JSONObject jsonObject = JSON.parseObject(json);
            String freezingRange = jsonObject.get("freezingRange").toString();
            //判断冻结状态
            if(StringUtils.equals(freezingRange,"1")){
                //这里如果freezingRange等于1,代表他是登录被冻结了直接抛异常  加上异常原因
                throw new MyException("登录被冻结!"+jsonObject.getString("reasonsForFreezing")));
            }
        }

以上为代码实现,哪里功能需要被冻结可以加上去,可以抽取工具类做方法传入登陆用户的手机号、状态类型即可(这里我使用的是状态类型string内容是数字)

扩展:

        我们还可以使用网关来限制同一个ip的发送多次注册,例如注册腾讯云同一个ip只能限制一次

        我们可以创建冻结表、解冻表、这样方便我们日后维护。比如查看哪些用户是惯犯?哪些用户被误封了,需要解封(使用解冻表,删除Redis中的key记录到解冻表中)?

当然一些人会问为什么要使用数据库来存储冻结表?使用日志不好?

原因有几点:

        1.我们这是后台管理系统,平时用的比较少,所以我们不用担心mysql数据库性能不够、存储量也不会太大。

        2.我们使用冻结表可以在记录到Redis时候记录下来,这样可以防止Redis宕机数据丢失。

        3.我们使用日志还需要解析日志才能得到数据。

   

        

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值