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
数据校验方案
/** * 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小时内删除侵权内容。
暂时没有评论,来抢沙发吧~