首页 > 其他分享 >Token持久化存储

Token持久化存储

时间:2023-09-23 13:35:41浏览次数:39  
标签:username map 存储 持久 String token Token template public

Token持久化存储

我们之前使用SpringSecurity时,remember-me的Token是支持持久化存储的,而我们当时是存储在数据库中,那么Token信息能否存储在缓存中呢,当然也是可以的,我们可以手动实现一个:

//实现PersistentTokenRepository接口
@Component
public class RedisTokenRepository implements PersistentTokenRepository {
  	//Key名称前缀,用于区分
    private final static String REMEMBER_ME_KEY = "spring:security:rememberMe:";
    @Resource
    RedisTemplate<Object, Object> template;

    @Override
    public void createNewToken(PersistentRememberMeToken token) {
      	//这里要放两个,一个存seriesId->Token,一个存username->seriesId,因为删除时是通过username删除
        template.opsForValue().set(REMEMBER_ME_KEY+"username:"+token.getUsername(), token.getSeries());
        template.expire(REMEMBER_ME_KEY+"username:"+token.getUsername(), 1, TimeUnit.DAYS);
        this.setToken(token);
    }

  	//先获取,然后修改创建一个新的,再放入
    @Override
    public void updateToken(String series, String tokenValue, Date lastUsed) {
        PersistentRememberMeToken token = this.getToken(series);
        if(token != null)
           this.setToken(new PersistentRememberMeToken(token.getUsername(), series, tokenValue, lastUsed));
    }

    @Override
    public PersistentRememberMeToken getTokenForSeries(String seriesId) {
        return this.getToken(seriesId);
    }

  	//通过username找seriesId直接删除这两个
    @Override
    public void removeUserTokens(String username) {
        String series = (String) template.opsForValue().get(REMEMBER_ME_KEY+"username:"+username);
        template.delete(REMEMBER_ME_KEY+series);
        template.delete(REMEMBER_ME_KEY+"username:"+username);
    }

  
  	//由于PersistentRememberMeToken没实现序列化接口,这里只能用Hash来存储了,所以单独编写一个set和get操作
    private PersistentRememberMeToken getToken(String series){
        Map<Object, Object> map = template.opsForHash().entries(REMEMBER_ME_KEY+series);
        if(map.isEmpty()) return null;
        return new PersistentRememberMeToken(
                (String) map.get("username"),
                (String) map.get("series"),
                (String) map.get("tokenValue"),
                new Date(Long.parseLong((String) map.get("date"))));
    }

    private void setToken(PersistentRememberMeToken token){
        Map<String, String> map = new HashMap<>();
        map.put("username", token.getUsername());
        map.put("series", token.getSeries());
        map.put("tokenValue", token.getTokenValue());
        map.put("date", ""+token.getDate().getTime());
        template.opsForHash().putAll(REMEMBER_ME_KEY+token.getSeries(), map);
        template.expire(REMEMBER_ME_KEY+token.getSeries(), 1, TimeUnit.DAYS);
    }
}

接着把验证Service实现了:

@Service
public class AuthService implements UserDetailsService {

    @Resource
    UserMapper mapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Account account = mapper.getAccountByUsername(username);
        if(account == null) throw new UsernameNotFoundException("");
        return User
                .withUsername(username)
                .password(account.getPassword())
                .roles(account.getRole())
                .build();
    }
}

Mapper也安排上:

@Data
public class Account implements Serializable {
    int id;
    String username;
    String password;
    String role;
}
@CacheNamespace(implementation = MybatisRedisCache.class)
@Mapper
public interface UserMapper {

    @Select("select * from users where username = #{username}")
    Account getAccountByUsername(String username);
}

最后配置文件配一波:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .formLogin()
            .and()
            .rememberMe()
            .tokenRepository(repository);
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
            .userDetailsService(service)
            .passwordEncoder(new BCryptPasswordEncoder());
}

OK,启动服务器验证一下吧。

标签:username,map,存储,持久,String,token,Token,template,public
From: https://www.cnblogs.com/liuzonglin/p/17724267.html

相关文章

  • 【数据的存储】(深度剖析)
    (文章目录)1.前言在计算机系统中,无论是整型数据还是浮点型数据,它们都是以二进制信息单元0、1的形式表示。我们在平常编程中,经常会使用不同的数据类型,那么大家想过它们在内存中是如何存储的吗?本篇博客就带大家走进数据的世界!2.进制的引入<arel="nofollow"href="#https://www.c......
  • mysql存储过程
    CREATETABLE`member`(`lv_id`int(255)NOTNULLAUTO_INCREMENT,`uname`varchar(255)DEFAULTNULL,`email`varchar(255)DEFAULTNULL,`passwd`varchar(255)DEFAULTNULL,`sex`int(11)DEFAULTNULL,PRIMARYKEY(`lv_id`))ENGINE=InnoDBAUTO_INCREME......
  • 【Java 基础篇】Java HashSet 集合详解:高效存储唯一元素的利器
    Java中的集合框架提供了各种各样的数据结构,用于存储和操作数据。其中,HashSet是一种常用的集合类,它实现了Set接口,用于存储不重复的元素。本篇博客将详细介绍HashSet的基本概念、创建和初始化、基本操作、遍历、性能考虑、使用注意事项以及示例代码。无论您是初学者还是有经验......
  • 【Java 基础篇】Java LinkedHashSet 详解:有序唯一元素存储的完美选择
    Java中的集合框架提供了多种数据结构,用于存储和操作数据。LinkedHashSet是其中的一个特殊类型,它结合了哈希表和链表的特性,适用于需要保持元素插入顺序并确保唯一性的情况。本篇博客将详细介绍LinkedHashSet,包括它的概念、特性、使用方法以及示例代码,旨在帮助初学者更好地理解和......
  • ClickHouse的数据持久化与恢复机制
    简介ClickHouse是一个高性能的列式数据库,它的数据持久化和恢复机制是其重要的特性之一。本文将深入探讨ClickHouse的数据持久化与恢复机制。数据持久化ClickHouse的数据持久化是通过将数据写入磁盘来实现的。ClickHouse使用了一种称为MergeTree的存储引擎,它将数据按照时间戳分成......
  • Kafka消息消费者位移存储性能测试
    背景Kafka是一个高性能、分布式的消息队列,被广泛应用于大数据领域。在Kafka中,消费者位移存储是非常重要的一部分,它记录了消费者消费消息的位置,以便在消费者宕机或者重启后能够继续消费未消费的消息。在实际应用中,消费者位移存储的性能对于Kafka的整体性能有着重要的影响。本文将......
  • Hadoop是什么? Hadoop是一个由Apache开发的开源分布式计算框架,它能够处理大规模数据并
    Hadoop是什么?Hadoop是一个由Apache开发的开源分布式计算框架,它能够处理大规模数据并行处理任务,支持大规模数据存储和处理。Hadoop的核心组件包括分布式文件系统HDFS和分布式计算框架MapReduce,它们使得Hadoop可以在廉价的硬件上并行地处理大量数据。Hadoop还包括很多相关的项目和子......
  • EasyGBS视频存储为什么是视频监控系统平台的重要组成部分
    ​EasyGBS是一个高度灵活、功能丰富的视频监控系统,其强大的拓展性和便捷的部署方式使其在众多场景中都能发挥出色的性能。EasyCVR平台支持多种主流标准协议,包括但不限于国标GB28181、RTSP/Onvif、RTMP等,这些协议为设备之间的互联互通提供了基础。数据安全性与稳定性:视频存储......
  • 智慧乡村:视频存储管理平台 EasyCVR 怎么样去助力乡村数字化?
    EasyCVR是一个高度灵活、功能丰富的视频监控系统,其强大的拓展性和便捷的部署方式使其在众多场景中都能发挥出色的性能。EasyCVR平台支持多种主流标准协议,包括但不限于国标GB28181、RTSP/Onvif、RTMP等,这些协议为设备之间的互联互通提供了基础。一、需求分析:某镇22个村庄,合......
  • Easy CVR视频存储平台怎么样才能快捷判断视频流编码格式?
    EasyCVR是一个功能强大的设备接入平台,它支持多种设备接入协议,并能够分发多种视频格式的视频流。同时,它还提供视频监控直播、云端录像、云存储、录像检索与回看、智能告警、平台级联、智能分析等多种视频服务,能够满足用户在视频监控领域的需求。无论是个人用户还是企业用户,都可以......