redis 分布式集群 登录令牌共享实现方案 采用redis 加mysql 实现一处登录 多处校验实现方案

网友投稿 929 2022-10-10

redis 分布式集群 登录令牌共享实现方案 采用redis 加mysql 实现一处登录 多处校验实现方案

redis 分布式集群 登录令牌共享实现方案 采用redis 加mysql 实现一处登录 多处校验实现方案

目录

​​介绍​​

​​实现方案​​

​​redis 配置方案​​

​​java配置​​

​​java 校验 -实现方案​​

​​redis 中用户令牌,数据存储方案​​

​​redis uitl 类​​

​​数据校验方案​​

​​发现一些路径地址的请求,就对地址进行权限校验即可​​

介绍

为支持服务用户量越来越多,设计分布式集群,在集群中登录和校验登录令牌,为一个重要的事情,

为实现又快又稳又方便的服务,所谓增加机器成本比增加开发成本要先考虑,于是设计如下方案

实现方案

1.使用redis 存储登录的令牌 和用户权限信息

2.如果有需要也可以放些别的东西,更具业务而定

3.也更具业务需求,要快或其他思路可以纯放普通东西

4.有时候一些系统对普通用户完全不用考虑权限,那就更不用加权限这玩意了

redis 配置方案

1.redis 配置 多ip可以访问

2.这样可以让多台服务都能访问到

3.配置aof 持久化保存数据

java配置

#-------------------------------------------------集成redis配置 ------------------------------------------#spring: redis: #url: redis://user:password@192.168.38.129:6379 #该地址配置以后会重置host,port,password的规则。 host: 192.168.38.129 port: 6379 #密码 password: xxxx database: 0 #指定数据库,默认为0 timeout: 300 #连接超时时间,单位毫秒,默认为0 ssl: false # 是否启用SSL连接,默认false jedis: pool: #连接池配置 max-active: 8 #最大活跃连接数,默认8个。 max-idle: 8 #最大空闲连接数,默认8个。 max-wait: -1 #获取连接的最大等待时间,默认-1,表示无限制,单位毫秒。默认值可能会因为获取不到连接,导致事务无法提交,数据库被锁,大量线程处于等待状态的情况。 min-idle: 0 #最小空闲连接数,默认0。 #sentinel: # master: mymaster #哨兵mastser # nodes: host1:port,host2:port #哨兵节点 #cluster: # max-redirects: # 集群模式下,集群最大转发的数量 # nodes: host1:port,host2:port # 集群节点#-------------------------------------------------集成redis配置 ------------------------------------------

java 校验 -实现方案

一层数据获取到值后将数据带出来,放到下边的值进行使用

简单点讲,就是获取用户登录信息的时候,读取了一次redis,然后将redis中的用户信息放到内存缓存中

在后边的权限校验的时候直接进行使用

又快又好

redis 中用户令牌,数据存储方案

redis 存令牌可以使用用户id作为唯一key 存储

采用key val 的基础存法

有需要还可以采用 id前边加上项目名称或信息,方便别别多个项目,但一般一个项目搞一个,没必要多个项目都放到一起,如此甚好

redis uitl 类

package com.superman.base.redis.uitl;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Component;import org.springframework.util.CollectionUtils;import com.alibaba.druid.support.logging.Log;import com.alibaba.druid.support.logging.LogFactory;import com.superman.tonifi.JSONOrTextOut;import java.util.List;import java.util.Map;import java.util.Set;import java.util.concurrent.TimeUnit;@Componentpublic final class RedisUtil { private final static Log log = LogFactory.getLog(RedisUtil.class); @Autowired private RedisTemplate redisTemplate; // =============================common============================ /** * 指定缓存失效时间 * @param key 键 * @param time 时间(秒) */ public boolean expire(String key, long time) { try { if (time > 0) { redisTemplate.expire(key, time, TimeUnit.SECONDS); } return true; } catch (Exception e) { log.error(e.toString()); return false; } } /** * 根据key 获取过期时间 * @param key 键 不能为null * @return 时间(秒) 返回0代表为永久有效 */ public long getExpire(String key) { return redisTemplate.getExpire(key, TimeUnit.SECONDS); } /** * 判断key是否存在 (不建议使用) * 由于序列号等各类型原因不方便,还是直接使用 Object c = get(key); c==null 来判断使用 * @param key 键 * @return true 存在 false不存在 */ public boolean hasKey(String key) { try {// Object c = redisTemplate.opsForValue().get(key);// return c==null?false:true; //由于序列化的原因,hasKey 一直返回false 可以使用上边方法,或使用修改redis修改序列号实现下边使用 return redisTemplate.hasKey(key); } catch (Exception e) { log.error(e.toString()); return false; } } /** * 删除缓存 * @param key 可以传一个值 或多个 */ @SuppressWarnings("unchecked") public void del(String... key) { if (key != null && key.length > 0) { if (key.length == 1) { redisTemplate.delete(key[0]); } else { redisTemplate.delete(CollectionUtils.arrayToList(key)); } } } // ============================String============================= /** * 普通缓存获取 * @param key 键 * @return 值 */ public Object get(String key) { return key == null ? null : redisTemplate.opsForValue().get(key); } /** * 普通缓存放入 * @param key 键 * @param value 值 * @return true成功 false失败 */ public boolean set(String key, Object value) { try { redisTemplate.opsForValue().set(key, value); return true; } catch (Exception e) { log.error(e.toString()); return false; } } /** * 普通缓存放入并设置时间 * @param key 键 * @param value 值 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 * @return true成功 false 失败 */ public boolean set(String key, Object value, long time) { try { if (time > 0) { redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); } else { set(key, value); } return true; } catch (Exception e) { log.error(e.toString()); return false; } } /** * 递增 * @param key 键 * @param delta 要增加几(大于0) */ public long incr(String key, long delta) { if (delta < 0) { throw new RuntimeException("递增因子必须大于0"); } return redisTemplate.opsForValue().increment(key, delta); } /** * 递减 * @param key 键 * @param delta 要减少几(小于0) */ public long decr(String key, long delta) { if (delta < 0) { throw new RuntimeException("递减因子必须大于0"); } return redisTemplate.opsForValue().increment(key, -delta); } // ================================Map================================= /** * HashGet * @param key 键 不能为null * @param item 项 不能为null */ public Object hget(String key, String item) { return redisTemplate.opsForHash().get(key, item); } /** * 获取hashKey对应的所有键值 * @param key 键 * @return 对应的多个键值 */ public Map hmget(String key) { return redisTemplate.opsForHash().entries(key); } /** * HashSet * @param key 键 * @param map 对应多个键值 */ public boolean hmset(String key, Map map) { try { redisTemplate.opsForHash().putAll(key, map); return true; } catch (Exception e) { log.error(e.toString()); return false; } } /** * HashSet 并设置时间 * @param key 键 * @param map 对应多个键值 * @param time 时间(秒) * @return true成功 false失败 */ public boolean hmset(String key, Map map, long time) { try { redisTemplate.opsForHash().putAll(key, map); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { log.error(e.toString()); return false; } } /** * 向一张hash表中放入数据,如果不存在将创建 * * @param key 键 * @param item 项 * @param value 值 * @return true 成功 false失败 */ public boolean hset(String key, String item, Object value) { try { redisTemplate.opsForHash().put(key, item, value); return true; } catch (Exception e) { log.error(e.toString()); return false; } } /** * 向一张hash表中放入数据,如果不存在将创建 * * @param key 键 * @param item 项 * @param value 值 * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 * @return true 成功 false失败 */ public boolean hset(String key, String item, Object value, long time) { try { redisTemplate.opsForHash().put(key, item, value); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { log.error(e.toString()); return false; } } /** * 删除hash表中的值 * * @param key 键 不能为null * @param item 项 可以使多个 不能为null */ public void hdel(String key, Object... item) { redisTemplate.opsForHash().delete(key, item); } /** * 判断hash表中是否有该项的值 * * @param key 键 不能为null * @param item 项 不能为null * @return true 存在 false不存在 */ public boolean hHasKey(String key, String item) { return redisTemplate.opsForHash().hasKey(key, item); } /** * hash递增 如果不存在,就会创建一个 并把新增后的值返回 * * @param key 键 * @param item 项 * @param by 要增加几(大于0) */ public double hincr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, by); } /** * hash递减 * * @param key 键 * @param item 项 * @param by 要减少记(小于0) */ public double hdecr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, -by); } // ============================set============================= /** * 根据key获取Set中的所有值 * @param key 键 */ public Set sGet(String key) { try { return redisTemplate.opsForSet().members(key); } catch (Exception e) { log.error(e.toString()); return null; } } /** * 根据value从一个set中查询,是否存在 * * @param key 键 * @param value 值 * @return true 存在 false不存在 */ public boolean sHasKey(String key, Object value) { try { return redisTemplate.opsForSet().isMember(key, value); } catch (Exception e) { log.error(e.toString()); return false; } } /** * 将数据放入set缓存 * * @param key 键 * @param values 值 可以是多个 * @return 成功个数 */ public long sSet(String key, Object... values) { try { return redisTemplate.opsForSet().add(key, values); } catch (Exception e) { log.error(e.toString()); return 0; } } /** * 将set数据放入缓存 * * @param key 键 * @param time 时间(秒) * @param values 值 可以是多个 * @return 成功个数 */ public long sSetAndTime(String key, long time, Object... values) { try { Long count = redisTemplate.opsForSet().add(key, values); if (time > 0) expire(key, time); return count; } catch (Exception e) { log.error(e.toString()); return 0; } } /** * 获取set缓存的长度 * * @param key 键 */ public long sGetSetSize(String key) { try { return redisTemplate.opsForSet().size(key); } catch (Exception e) { log.error(e.toString()); return 0; } } /** * 移除值为value的 * * @param key 键 * @param values 值 可以是多个 * @return 移除的个数 */ public long setRemove(String key, Object... values) { try { Long count = redisTemplate.opsForSet().remove(key, values); return count; } catch (Exception e) { log.error(e.toString()); return 0; } } // ===============================list================================= /** * 获取list缓存的内容 * * @param key 键 * @param start 开始 * @param end 结束 0 到 -1代表所有值 */ public List lGet(String key, long start, long end) { try { return redisTemplate.opsForList().range(key, start, end); } catch (Exception e) { log.error(e.toString()); return null; } } /** * 获取list缓存的长度 * * @param key 键 */ public long lGetListSize(String key) { try { return redisTemplate.opsForList().size(key); } catch (Exception e) { log.error(e.toString()); return 0; } } /** * 通过索引 获取list中的值 * * @param key 键 * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 */ public Object lGetIndex(String key, long index) { try { return redisTemplate.opsForList().index(key, index); } catch (Exception e) { log.error(e.toString()); return null; } } /** * 将list放入缓存 * * @param key 键 * @param value 值 */ public boolean lSet(String key, Object value) { try { redisTemplate.opsForList().rightPush(key, value); return true; } catch (Exception e) { log.error(e.toString()); return false; } } /** * 将list放入缓存 * @param key 键 * @param value 值 * @param time 时间(秒) */ public boolean lSet(String key, Object value, long time) { try { redisTemplate.opsForList().rightPush(key, value); if (time > 0) expire(key, time); return true; } catch (Exception e) { log.error(e.toString()); return false; } } /** * 将list放入缓存 * * @param key 键 * @param value 值 * @return */ public boolean lSet(String key, List value) { try { redisTemplate.opsForList().rightPushAll(key, value); return true; } catch (Exception e) { log.error(e.toString()); return false; } } /** * 将list放入缓存 * * @param key 键 * @param value 值 * @param time 时间(秒) * @return */ public boolean lSet(String key, List value, long time) { try { redisTemplate.opsForList().rightPushAll(key, value); if (time > 0) expire(key, time); return true; } catch (Exception e) { log.error(e.toString()); return false; } } /** * 根据索引修改list中的某条数据 * * @param key 键 * @param index 索引 * @param value 值 * @return */ public boolean lUpdateIndex(String key, long index, Object value) { try { redisTemplate.opsForList().set(key, index, value); return true; } catch (Exception e) { log.error(e.toString()); return false; } } /** * 移除N个值为value * * @param key 键 * @param count 移除多少个 * @param value 值 * @return 移除的个数 */ public long lRemove(String key, long count, Object value) { try { Long remove = redisTemplate.opsForList().remove(key, count, value); return remove; } catch (Exception e) { log.error(e.toString()); return 0; } }}

数据校验方案

/** * redis 校验在线用户 * * @param userid * @param token * @param url * @param userDeptData 获取权限代码数据 * * @return boolean true false * */ public boolean redisOnlineCheckv2(String userid,String token,String url,String userDeptData){ Object c = ru.get("xxxxporject_"+userid); if(c!=null){ String tokenData = c.toString(); //使用 &dept_code= 区分token 和权限 0位置 token 一位置权限代码,多个用英文逗号,隔开 if(tokenData.contains("&dept_code=")){ if(tokenData.split("&dept_code=")[0].equals(token)){ userDeptData = tokenData.split("&dept_code=").length>=2?tokenData.split("&dept_code=")[1]:""; log.info(url+" visit "+userid+" token:"+token+" seccess "); return true; }else{ log.info(url+" visit "+userid+" token:"+token+" token check fial "); return false; } }else{ log.info(url+" visit "+userid+" token:"+token+" token check fial "); return false; } }else{ log.info(url+" visit "+userid+" token:"+token+" redis null userid "); return false; } }

可以在-中 进行加上上边的校验方法

发现一些路径地址的请求,就对地址进行权限校验即可

/** * redis用户权限校验 * * @author jianghy * * @param userid 用户id * @param deptCode 权限id * @param userDeptData 用户所有权限代码 * * @return true 、 false */ public boolean redisdeptCheck(String userid,String deptCode,String userDeptData){ if(userDeptData.contains(",")){ String[] arr = userDeptData.split(","); for (int i = 0; i < arr.length; i++) { if(arr[i].equals(deptCode)){//校验每个权限,有权限的返回通过,否则返回未通过 return true; } } return false; }else{ return false; } }

ok

持续更新

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Crispy- 远程调用框架(crispy trolls)
下一篇:CRMEB- 微信商城小程序商城系统(crmeb是真开源的吗)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~