Springboot2 + Shiro + Redis + Jwt 前后端分离整合(4)

继上一篇 Springboot2 + Shiro + Redis + Jwt 前后端分离整合(3) 继续补充

码云项目地址 : Springboot + shiro + redis + jwt + jpa

使用自己的redis缓存机制

重写redisCache—CustimCache类

@Slf4j
public class CustomCache<K,V> implements Cache<K,V> {


    /**
     * 缓存的key名称获取为shiro:cache:account
     * @param key
     */
    private String getKey(K key) {
        String userId;
        if (key instanceof PrincipalCollection) {
            UserEntity user = (UserEntity) ((PrincipalCollection)key).getPrimaryPrincipal();
            userId= TokenUtil.getField(user.getToken(), "userId",Long.class).toString();
        } else {
            userId = key.toString();
        }

        return ShiroConstant.ROLE_SHIRO_CACHE + userId;
    }

    /**
     * 获取缓存
     */
    @Override
    public V get(K key) throws CacheException {
    if (!RedisUtil.hasKey(this.getKey(key))) {
        return null;
    }

    Object o = RedisUtil.get(this.getKey(key));
    V v = (V)o;

    return (V)o;
    }

    /**
     * 保存缓存
     */
    @Override
    public V put(K key, V value) throws CacheException {
        RedisUtil.set(this.getKey(key), value);
        return value;
    }

    /**
     * 移除缓存
     */
    @Override
    public V remove(K key) throws CacheException {
        if (!RedisUtil.hasKey(this.getKey(key))) {
            return null;
        }
        RedisUtil.del(this.getKey(key));
        return null;
    }

    /**
     * 清空所有缓存
     */
    @Override
    public void clear() throws CacheException {

    }

    /**
     * 缓存的个数
     */
    @Override
    public Set<K> keys() {
        return null;
    }

    /**
     * 获取所有的key
     */
    @Override
    public int size() {
        return 0;
    }

    /**
     * 获取所有的value
     */
    @Override
    public Collection<V> values() {
        return null;
    }
}

缓存管理器CustomCacheManager

public class CustomCacheManager implements CacheManager {
    @Override
    public <K, V> Cache<K, V> getCache(String s) throws CacheException {
        return new CustomCache<K, V>();
    }
}

修改ShiroConfig中的securityManager方法就可以了

    @Bean(name = "securityManager")
    public org.apache.shiro.mgt.SecurityManager securityManager(AuthRealm realm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(realm);
//        //使用shiro的redis缓存
//        securityManager.setCacheManager(cacheManager());

        //使用自己的redis缓存
        securityManager.setCacheManager(new CustomCacheManager());
        //关闭Shiro自带的session
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
        defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
        securityManager.setSubjectDAO(subjectDAO);

        return securityManager;
    }

shiro登出出来的问题

因我们不使用shiro的session机制,所以不能用shiro自带的logout来清除缓存,但是单单用subject.logout(),这只会清除redis中的角色权限缓存,不会清除认证缓存

在这里插入图片描述

    @PostMapping("/logout")
    public Map<String, Object> logout() {
        Subject sub = SecurityUtils.getSubject();
        // sub.logout应该放到 user获取之后,不然user获取到为空
        //  这里感谢  淘气包丶  大兄弟指出问题所在  
        UserEntity user = (UserEntity)sub.getPrincipal();
        sub.logout();
        RedisUtil.del(ShiroConstant.LOGIN_SHIRO_CACHE + user.getId());
        Map<String, Object> result = new HashMap<>();
        result.put("status", "200");
        result.put("msg", "登出成功");
        return result;
    }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值