springboot + spring security + jwt + redis详细(一)

作为一个刚入门,没多久的新手小白,由于项目需要,所以学习了一下spring security,基本上此篇文章是根据各路大神撰写的博客结合而来,为了同样刚接触的新手小白少踩点坑,因为是给小白们看能拿来就用那种,所以代码比较多,请耐心看完,有什么问题还请大神们多多指点(注:为了不误导新手,此博客仅供参考)

创建用户表:

	CREATE TABLE `sys_user` (
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
      `username` varchar(200) NOT NULL,
      `password` varchar(200) NOT NULL,
      PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

用户角色表

CREATE TABLE `sys_role` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(200) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

用户角色-关系表

CREATE TABLE `sys_role_user` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `sys_user_id` bigint(20) unsigned NOT NULL,
  `sys_role_id` bigint(20) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

权限表

CREATE TABLE `sys_permission` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(200) NOT NULL,
  `description` varchar(200) DEFAULT NULL,
  `url` varchar(200) NOT NULL,
  `pid` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

角色权限-关系表

CREATE TABLE `sys_permission_role` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `role_id` bigint(20) unsigned NOT NULL,
  `permission_id` bigint(20) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;

在pom.xml中添加security和jwt的相关依赖


        org.springframework.security
        spring-security-test
        test
    
    
        org.springframework.boot
        spring-boot-starter-security
    
    
    
        io.jsonwebtoken
        jjwt
        0.9.0
    
    
        org.springframework.boot
        spring-boot-starter-redis
        1.3.8.RELEASE
    

2、在application.yml中配置mysql及jwt等

server:
  port: 8081

spring:
  datasource:
    druid:
      # MySQL 8.x: com.mysql.cj.jdbc.Driver
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/数据库?serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
      username: root
      password: 密码
      initial-size: 1
      min-idle: 1
      max-active: 20
      test-on-borrow: true
      view:
        prefix: /static/
  redis:
    host: 127.0.0.1
    port: 6379
    password:
    timeout: 3600
  http:
    encoding:
      charset: UTF-8
      force: true
      enabled: true

mybatis:
  #实体类的存放路径,如:com.funtl.hello.spring.boot.entity
  type-aliases-package: com.personnel.entity
  mapper-locations: classpath:mapper/*.xml
  #开启驼峰命名转换
  configuration:
    map-underscore-to-camel-case: true


jasypt:
  encryptor:
    password: 123456


jwt:
  tokenHeader: Authorization
  tokenPrefix: Bearer
  secret: lanjwt
  expiration: 3600
  rememberExpiration: 604800

#自定义参数,可以迁移走
token:
  #token失效时间(不是refreshToken)(这是自定义的)(秒)
  expirationSeconds: 300

  #默认7天登录有效(根据业务更改)
  validTime: 7

创建实体、Dao、Service和Controller
实体类 我是用 tk.mybatis自动生成的,如果有兴趣的可以参考这篇文章Spring Boot 整合 tk.mybatis

实体类 SysUser

package com.personnel.entity;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Collection;
import java.util.Set;

@Table(name = "sys_user")
public class SysUser implements UserDetails, Serializable {
    private static final long serialVersionUID = 7171722954972237961L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;

    private String password;

    private Set authorities;

	// 省略getter/setter
   
}

实体类 SysRoleUser

package com.personnel.entity;

import javax.persistence.*;

@Table(name = "sys_role_user")
public class SysRoleUser {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "sys_user_id")
    private Long sysUserId;

    @Column(name = "sys_role_id")
    private Integer sysRoleId;

    // 省略getter/setter
}

实体类 SysRole

package com.personnel.entity;

import javax.persistence.*;

@Table(name = "sys_role")
public class SysRole {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

   // 省略getter/setter
}

实体类 SysPermissionRole

package com.personnel.entity;

import javax.persistence.*;

@Table(name = "sys_permission_role")
public class SysPermissionRole {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "role_id")
    private Long roleId;

    @Column(name = "permission_id")
    private Long permissionId;

   // 省略getter/setter
}

Dao 层 SysUserMapper


public interface SysUserMapper extends MyMapper {
    //通过username查询用户
    @Select("select * from sys_user where username = #{username}")
    SysUser getUser(@Param("username") String username);

}

Dao 层 SysRoleUserMapper


public interface SysRoleUserMapper extends MyMapper {
}

Dao 层 SysRoleMapper

public interface SysRoleMapper extends MyMapper {
}

Dao 层 SysRoleMapper

public interface SysPermissionRoleMapper extends MyMapper {
}

Dao 层 SysPermissionMapper

public interface SysPermissionMapper extends MyMapper {

    @Select("SELECT * from Sys_permission")
    public List findAll();

    @Select("select p.*" +
            "from Sys_User u" +
            "LEFT JOIN sys_role_user sru on u.id= sru.Sys_User_id" +
            "LEFT JOIN Sys_Role r on sru.Sys_Role_id=r.id" +
            "LEFT JOIN Sys_permission_role spr on spr.role_id=r.id" +
            "LEFT JOIN Sys_permission p on p.id =spr.permission_id" +
            "where u.id=#{userId}")

    public List findByAdminUserId(int userId);
}

Service层 SysUserService


public interface SysUserService {

    SysUser findUserById(Integer id);

    List findUserByName(String username);

    void insert(SysUser user);
}

Service层 SysUserRoleService


public interface SysUserRoleService {

    List findRoleListByUserId(Long userId);

    void insert(int id, Integer roleId);
}

Service层 SysRoleService


public interface SysRoleService {

    public SysRole findRoleById(Long id);

    public SysRole findRoleByName(String name);
}

Service层 SysPermissionService


public interface SysPermissionService {

    public SysPermission findResourceByUrl(String url);
}

Service层 SysPermissionRoleService

package com.personnel.service;

import com.personnel.entity.SysPermissionRole;

import java.util.List;

public interface SysPermissionRoleService {
    public List fingSysResourceRoleKeyByResId(Long resId);
}

impl 层 SysUserServiceImpl

@Service
public class SysUserServiceImpl implements SysUserService {
    @Autowired
    SysUserMapper sysUserMapper;
    @Override
    public SysUser findUserById(Integer id){
        SysUser sysUser = sysUserMapper.selectByPrimaryKey(id);
        return sysUser;
    }
    @Override
    public List findUserByName(String username){
        Example sysUserExample =new Example(SysUser.class);
        sysUserExample.createCriteria().andEqualTo("username",username);
        List sysUsers = sysUserMapper.selectByExample(sysUserExample);
        return sysUsers;
    }

    @Override
    public SysUser UserByName(String username){
        SysUser sysUsers = sysUserMapper.getUser(username);
        return sysUsers;
    }

    @Override
    public void insert(SysUser user) {
        sysUserMapper.insertSelective(user);
    }
}

impl 层 SysUserRoleServiceImpl

@Service
public class SysUserRoleServiceImpl implements SysUserRoleService {
    private static final Logger logger = LoggerFactory.getLogger(SysUserRoleServiceImpl.class);
    @Autowired
    SysRoleUserMapper sysRoleUserMapper;
    @Override
    public List findRoleListByUserId(Long userId){
        Example sysUserRoleExample =new Example(SysRoleUser.class);
        sysUserRoleExample.createCriteria().andEqualTo("sysUserId",userId);

        List sysRoleUsers = sysRoleUserMapper.selectByExample(sysUserRoleExample);
        logger.info("根据userId查询到的Roles"+sysRoleUsers.toString());
        return sysRoleUsers;
    }

    @Override
    public void insert(int id, Integer roleId) {
        SysRoleUser sysRoleUser = new SysRoleUser();
        sysRoleUser.setSysRoleId(roleId);
        sysRoleUser.setSysUserId((long) id);
        sysRoleUserMapper.insertSelective(sysRoleUser);

    }
}

impl 层 SysRoleServiceImpl

@Service
public class SysRoleServiceImpl implements SysRoleService {
    private static final Logger logger = LoggerFactory.getLogger(SysRoleServiceImpl.class);
    @Autowired
    SysRoleMapper sysRoleMapper;

    @Override
    public SysRole findRoleById(Long id) {
        SysRole sysRole = sysRoleMapper.selectByPrimaryKey(id);
        logger.info("根据id查询到的role:" + sysRole.toString());
        return sysRole;
    }

    @Override
    public SysRole findRoleByName(String name) {
        Example sysRoleExample =new Example(SysRole.class);
        sysRoleExample.createCriteria().andEqualTo("name",name);
        List sysRoles = sysRoleMapper.selectByExample(sysRoleExample);
        if(sysRoles == null || sysRoles.size()==0){
            return null;
        }
        return sysRoles.get(0);
    }

}

impl 层 SysPermissionServiceImpl

@Service
public class SysPermissionServiceImpl implements SysPermissionService {

    @Autowired
    SysPermissionMapper sysPermissionMapper;
    @Override
    public SysPermission findResourceByUrl(String url) {
        Example sysResourceExample =new Example(SysPermission.class);
        sysResourceExample.createCriteria().andEqualTo("url",url);
        List sysResources = sysPermissionMapper.selectByExample(sysResourceExample);
        if(sysResources == null || sysResources.size()==0){
            return null;
        }
        return sysResources.get(0);
    }
}

impl 层 SysPermissionRoleServiceImpl

@Service
public class SysPermissionRoleServiceImpl implements SysPermissionRoleService {

    @Autowired
    SysPermissionRoleMapper sysPermissionRoleMapper;
    @Override
    public List fingSysResourceRoleKeyByResId(Long resId) {
        Example sysResourceRoleExample =new Example(SysPermissionRole.class);
        sysResourceRoleExample.createCriteria().andEqualTo("id",resId);

        List sysResourceRoleKeys = sysPermissionRoleMapper.selectByExample(sysResourceRoleExample);
        return sysResourceRoleKeys;
    }

}

Controller层 LoginController

@RestController
public class LoginController {
    private Logger logger = LoggerFactory.getLogger(LoginController.class);
    @Autowired
    SysUserService sysUserService;
    @Autowired
    SysRoleService sysRoleService;
    @Autowired
    SysUserRoleService sysUserRoleService;

    @RequestMapping("/")
    public String showHome() {
        String name = SecurityContextHolder.getContext().getAuthentication().getName();
        logger.info("当前登陆用户:" + name);

        return "home";
    }

    @RequestMapping("/login")
    public String showLogin() {
        return "login";
    }

    @RequestMapping("/admin")
    @ResponseBody
    /* @PreAuthorize("hasPermission('/admin','r')")*/
    public String printAdmin() {
        return "如果你看见这句话,说明你可以访问/admin路径";
    }

    @RequestMapping("/user")
    @ResponseBody
    /*@PreAuthorize("hasPermission('/user','c')")*/
    public String printUser() {
        return "如果你看见这句话,说明你可以访问/user路径";
    }

    @RequestMapping("/all")
    @ResponseBody
    /*@PreAuthorize("hasPermission('/user','c')")*/
    public String printAll() {
        return "如果你看见这句话,说明你可以访问/all路径";
    }

    @RequestMapping(value = "/register", method = RequestMethod.GET)
    public String showRegister() {
        return "register";
    }

    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public Object register(SysUser user, Integer[] roles) throws Exception {
        String name = user.getUsername();

        if (StringUtils.isEmpty(name) || StringUtils.isEmpty(user.getPassword())) {
            throw new Exception("输入数据错误");
        }

        if (sysUserService.findUserByName(name) != null && sysUserService.findUserByName(name).size()>0 ) {
            throw new Exception("用户名已被注册");
        }

        user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()));
        sysUserService.insert(user);
        int id = Math.toIntExact(sysUserService.findUserByName(name).get(0).getId());
        for (Integer roleId : roles) {
            sysUserRoleService.insert(id, roleId);
        }
        return "redirect:/login";
    }

    @RequestMapping("/login/error")
    public String loginError(HttpServletRequest request) {
        AuthenticationException exception = (AuthenticationException) request.getSession().getAttribute("SPRING_SECURITY_LAST_EXCEPTION");
        Msg msg = new Msg<>(false, exception.getMessage(), exception.toString());
        request.getSession().removeAttribute("msg");
        request.getSession().setAttribute("msg", msg);
        return "login";
    }

配置SpringSecurity- UserDetailsService
自定义 UserDetailsService ,将用户信息和权限注入进来。
重写 loadUserByUsername 方法,参数是用户输入的用户名。返回值是UserDetails,这是一个接口,一般使用它的子类org.springframework.security.core.userdetails.User,它有三个参数,分别是用户名、密码和权限集。

@Service
public class CustomUserDetailsService implements UserDetailsService {
    @Autowired
    SysRoleService sysRoleService;
    @Autowired
    SysUserService sysUserService;
    @Autowired
    SysUserRoleService sysUserRoleService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Collection grantedAuthorities = new ArrayList<>();
        List users = sysUserService.findUserByName(username);
        if(users == null && users.size()<1){
            throw new UsernameNotFoundException("用户名不存在");
        }

        SysUser sysUser = users.get(0);
        List roleListByUserIds = sysUserRoleService.findRoleListByUserId(sysUser.getId());
        for (SysRoleUser roleListByUserId : roleListByUserIds) {
            SysRole sysRole = sysRoleService.findRoleById(roleListByUserId.getId());
            grantedAuthorities.add( new SimpleGrantedAuthority(sysRole.getName()));
        }
        return new User(sysUser.getUsername(),sysUser.getPassword(),grantedAuthorities);
    }
}

WebSecurityConfig
该类是 Spring Security 的配置类,该类的三个注解分别是标识该类是配置类、开启 Security 服务、开启全局 Securtiy 注解。自定义的 userDetailsService 注入进来,在 configure() 方法中使用 auth.userDetailsService() 方法替换掉默认的 userDetailsService

@Configuration
/*标识该类是配置类*/
@EnableWebSecurity
/*开启Security服务*/
@EnableGlobalMethodSecurity(prePostEnabled = true)
/*开启全局Securtiy注解*/
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    CustomUserDetailsService customUserDetailsService;
    @Autowired
    CustomAuthenticationFailureHandler customAuthenticationFailureHandler;
    @Autowired
    CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;
    //根据一个url请求,获得访问它所需要的roles权限
    @Autowired
    FilterInvocationSecurityMetadataSourceImpl filterInvocationSecurityMetadataSource;
    //接收一个用户的信息和访问一个url所需要的权限,判断该用户是否可以访问
    @Autowired
    AccessDecisionManagerImpl accessDecisionManager;
    //403页面
    @Autowired
    AccessDeniedHandlerImpl accessDeniedHandler;
    @Autowired
    DataSource dataSource;
    @Autowired
    private CustomUserDetailsService userDetailsService;

    @Autowired
    JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;

    @Bean
    public PersistentTokenRepository persistentTokenRepository(){
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        tokenRepository.setDataSource(dataSource);
        // 如果token表不存在,使用下面语句可以初始化该表;若存在,会报错。
        //tokenRepository.setCreateTableOnStartup(true);
        return tokenRepository;
    }
    @Override
    /**定义认证用户信息获取来源,密码校验规则等,注释部分为明文密码验证方式,需要的话直接解除注释同时注释掉new BCryptPasswordEncoder()即可*/
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailsService).passwordEncoder(
             new BCryptPasswordEncoder()
//                new PasswordEncoder() {
//                      @Override
//                      public String encode(CharSequence charSequence) {
//                          return charSequence.toString();
//                      }
//
//                      @Override
//                      public boolean matches(CharSequence charSequence, String s) {
//                          return s.equals(charSequence.toString());
//                      }
//                  }
              );
    }

    @Override
    /**定义安全策略*/
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/register", "/getVerifyCode", "/hello").permitAll()
                //配置安全策略,就是拦截URL,验证访问权限的功能
                .withObjectPostProcessor(new ObjectPostProcessor() {
                    @Override
                    public  O postProcess(O o) {
                        o.setSecurityMetadataSource(filterInvocationSecurityMetadataSource);
                        o.setAccessDecisionManager(accessDecisionManager);
                        return o;
                    }
                })
                .and()
                // 设置登陆页
                .formLogin()
//                .loginPage("/login")
                //登录失败后的处理方式
                .failureHandler(customAuthenticationFailureHandler)
                //登录成功后的处理方式
                .successHandler(customAuthenticationSuccessHandler)
                .and()
                //验证码功能实现
//                .addFilterBefore(new VerifyFilter(), UsernamePasswordAuthenticationFilter.class)
                //退出登录
                .logout().permitAll()
                .logoutUrl("/logout")
//                .logoutSuccessUrl("/login")
                .and()
                // 关闭CSRF跨域
                .csrf().disable()
                .exceptionHandling()
                //403
                .accessDeniedHandler(accessDeniedHandler);

        // 记住我
        http.rememberMe().rememberMeParameter("remember-me")
                .userDetailsService(userDetailsService).tokenValiditySeconds(1000);
        http.exceptionHandling().accessDeniedHandler(accessDeniedHandler); // 无权访问 JSON 格式的数据
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); // JWT Filter
    }

    @Override
    //在这里配置哪些页面不需要认证
    public void configure(WebSecurity web) throws Exception {
        // 设置拦截忽略文件夹,可以对静态资源放行
        web.ignoring().antMatchers("/css/**", "/js/**");
    }

}

Jwt工具类

/**
 * @author: zzx
 * @date: 2018/10/16 9:06
 * @description: jwt生成token
 */
public class JwtTokenUtil {

    @Autowired
    private static RedisUtil redisUtil;

    // 寻找证书文件
    private static InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("jwt.jks"); // 寻找证书文件
    private static PrivateKey privateKey = null;
    private static PublicKey publicKey = null;

    public static final String TOKEN_HEADER = "Authorization";
    public static final String TOKEN_PREFIX = "Bearer ";

    private static final String SECRET = "jwtsecretdemo";
    private static final String ISS = "echisan";

    // 过期时间是3600秒,既是1个小时
    private static final long EXPIRATION = 3600L;

    // 选择了记住我之后的过期时间为7天
    private static final long EXPIRATION_REMEMBER = 604800L;

    // 创建token
    public static String createToken(String username, boolean isRememberMe) {
        long expiration = isRememberMe ? EXPIRATION_REMEMBER : EXPIRATION;
        return Jwts.builder()
                .signWith(SignatureAlgorithm.HS512, SECRET)
                .setIssuer(ISS)
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
                .compact();
    }

    // 从token中获取用户名
    public static String getUsername(String token){
        return getTokenBody(token).getSubject();
    }

    /**
     * 生成token
     * @param subject (主体信息)
     * @param expirationSeconds 过期时间(秒)
     * @param claims 自定义身份信息
     * @return
     */
    public static String generateToken(String subject, int expirationSeconds, Map claims) {
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(subject)
                .setExpiration(new Date(System.currentTimeMillis() + expirationSeconds * 1000))
//                .signWith(SignatureAlgorithm.HS512, salt) // 不使用公钥私钥
                .signWith(SignatureAlgorithm.RS256, privateKey)
                .compact();
    }

    /**
     * @author: zzx
     * @date: 2018-10-19 09:10
     * @deprecation: 解析token,获得subject中的信息
     */
    public static String parseToken(String token, String salt) {
        String subject = null;
        try {
            /*Claims claims = Jwts.parser()
//                    .setSigningKey(salt) // 不使用公钥私钥
                    .setSigningKey(publicKey)
                    .parseClaimsJws(token).getBody();*/
            subject = getTokenBody(token).getSubject();
        } catch (Exception e) {
        }
        return subject;
    }

    //获取token自定义属性
    public static Map getClaims(String token){
        Map claims = null;
        try {
            claims = getTokenBody(token);
        }catch (Exception e) {
        }

        return claims;
    }

    // 是否已过期
    public static boolean isExpiration(String expirationTime){
        /*return getTokenBody(token).getExpiration().before(new Date());*/

        //通过redis中的失效时间进行判断
        String currentTime = DateUtil.getTime();
        if(DateUtil.compareDate(currentTime,expirationTime)){
            //当前时间比过期时间小,失效
            return true;
        }else{
            return false;
        }
    }
    /**
     * 解密jwt,获得所有声明(包括标准和私有声明)
     *
     * @param
     * @return
     * @throws Exception
     */
    public static Claims getTokenBody(String token){
        return Jwts.parser()
                .setSigningKey(SECRET)
                .parseClaimsJws(token)
                .getBody();
    }
}

redis工具类

/**
 * @author: zzx
 * @date: 2018/10/23 10:31
 * @description: redis工具类
 */
@Component
public class RedisUtil {

    @Value("${token.expirationSeconds}")
    private int expirationSeconds;

    /*常量,各种实现方式都行,这里读取application.yml*/
    @Value("${token.validTime}")
    private int validTime;

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 查询key,支持模糊查询
     *
     * @param key 传过来时key的前后端已经加入了*,或者根据具体处理
     * */
    public Set keys(String key){
        return redisTemplate.keys(key);
    }

    /**
     * 字符串获取值
     * @param key
     * */
    public Object get(String key){
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 字符串存入值
     * 默认过期时间为2小时
     * @param key
     * */
    public void set(String key, String value){
        redisTemplate.opsForValue().set(key,value, 7200,TimeUnit.SECONDS);
    }

    /**
     * 字符串存入值
     * @param expire 过期时间(毫秒计)
     * @param key
     * */
    public void set(String key, String value,Integer expire){
        redisTemplate.opsForValue().set(key,value, expire,TimeUnit.SECONDS);
    }

    /**
     * 删出key
     * 这里跟下边deleteKey()最底层实现都是一样的,应该可以通用
     * @param key
     * */
    public void delete(String key){
        redisTemplate.opsForValue().getOperations().delete(key);
    }

    /**
     * 添加单个
     * 默认过期时间为两小时
     * @param key    key
     * @param filed  filed
     * @param domain 对象
     */
    public void hset(String key,String filed,Object domain){
        redisTemplate.opsForHash().put(key, filed, domain);
    }

    /**
     * 添加单个
     * @param key    key
     * @param filed  filed
     * @param domain 对象
     * @param expire 过期时间(毫秒计)
     */
    public void hset(String key,String filed,Object domain,Integer expire){
        redisTemplate.opsForHash().put(key, filed, domain);
        redisTemplate.expire(key, expire,TimeUnit.SECONDS);
    }

    /**
     * 添加HashMap
     *
     * @param key    key
     * @param hm    要存入的hash表
     */
    public void hset(String key, HashMap hm){
        redisTemplate.opsForHash().putAll(key,hm);
    }

    /**
     * 如果key存在就不覆盖
     * @param key
     * @param filed
     * @param domain
     */
    public void hsetAbsent(String key,String filed,Object domain){
        redisTemplate.opsForHash().putIfAbsent(key, filed, domain);
    }

    /**
     * 查询key和field所确定的值
     *
     * @param key 查询的key
     * @param field 查询的field
     * @return HV
     */
    public Object hget(String key,String field) {
        return redisTemplate.opsForHash().get(key, field);
    }

    /**
     * 查询该key下所有值
     *
     * @param key 查询的key
     * @return Map
     */
    public Object hget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * 删除key下所有值
     *
     * @param key 查询的key
     */
    public void deleteKey(String key) {
        redisTemplate.opsForHash().getOperations().delete(key);
    }

    /**
     * 判断key和field下是否有值
     *
     * @param key 判断的key
     * @param field 判断的field
     */
    public Boolean hasKey(String key,String field) {
        return redisTemplate.opsForHash().hasKey(key,field);
    }

    /**
     * 判断key下是否有值
     *
     * @param key 判断的key
     */
    public Boolean hasKey(String key) {
        return redisTemplate.opsForHash().getOperations().hasKey(key);
    }

    /**
     * 判断此token是否在黑名单中
     * @param token
     * @return
     */
    public Boolean isBlackList(String token){
        return hasKey("blacklist",token);
    }

    /**
     * 将token加入到redis黑名单中
     * @param token
     */
    public void addBlackList(String token){
        hset("blacklist", token,"true");
    }


    /**
     * 查询token下的刷新时间
     *
     * @param token 查询的key
     * @return HV
     */
    public Object getTokenValidTimeByToken(String token) {
        return redisTemplate.opsForHash().get(token, "tokenValidTime");
    }

    /**
     * 查询token下的刷新时间
     *
     * @param token 查询的key
     * @return HV
     */
    public Object getUsernameByToken(String token) {
        return redisTemplate.opsForHash().get(token, "username");
    }

    /**
     * 查询token下的刷新时间
     *
     * @param token 查询的key
     * @return HV
     */
    public Object getIPByToken(String token) {
        return redisTemplate.opsForHash().get(token, "ip");
    }

    /**
     * 查询token下的过期时间
     *
     * @param token 查询的key
     * @return HV
     */
    public Object getExpirationTimeByToken(String token) {
        return redisTemplate.opsForHash().get(token, "expirationTime");
    }

    public void setTokenRefresh(String token,String username,String ip){
        //刷新时间
        Integer expire = validTime*24*60*60*1000;

        hset(token, "tokenValidTime",DateUtil.getAddDayTime(validTime),expire);
        hset(token, "expirationTime",DateUtil.getAddDaySecond(expirationSeconds),expire);
        hset(token, "username",username,expire);
        hset(token, "ip",ip,expire);
    }
}


如果你看到这基本配置 就已经完成了

你可能感兴趣的:(java,spring,spring,boot,redis)