JWT权限验证

一.首先说一下 表

1.用户表

2.用户角色表

3.角色表

4.角色权限表

5.权限表(包含菜单表)

二.整个逻辑如下:

     1. 一个后台可能多个用户  (用户表)

             用户角色表连接 1 -  2 

     2.每一个用户可能用户多个角色,例如,AA用户 既是超级管理员  又是客服管理 (角色表)

             角色权限表 连接  2 - 3

     3.每个角色又有多种权限 ,例如,超级管理员,可以查看权限列表,后台客服管理又可以浏览日志模块,(权限表)

三 .表字段

     用户表: 基本字段 + ids(角色表id集合)

     角色表: id ,角色名称, 角色代码,描述,创建角色id, ids,权限ids 

     用户角色表: 用户id  ,角色id

     权限表: id,权限名称,权限代码,icon ,权限path, 排序sort. 菜单,父parentId 

     角色权限表: 角色id,权限id

四.JWT实现,引入JWT maven依赖, 



    io.jsonwebtoken
    jjwt
    0.6.0


 
     org.apache.commons
     commons-lang3
     3.4
 
 
 
     org.springframework.boot
     spring-boot-starter-security
 

JWTutil

import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

/**
 * JWT安全工具类
 * 
 * @ClassName: JwtUtil
 * @author xie
 * @date 2019年1月10日
 */
@ConfigurationProperties("jwt.config")
@Component
public class JwtUtil {

    private String key;

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    /**
     * 生成JWT
     *
     * @param id
     * @param subject
     * @return
     */
    public String createJWT(String id, String subject, String headPic, String roles, long ttl) {
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        JwtBuilder builder = Jwts.builder().setId(id).setSubject(subject).setIssuedAt(now)
                .signWith(SignatureAlgorithm.HS256, getKeyInstance(key)).claim("roles", roles)
                .claim("headPic", headPic);
        if (ttl > 0) {
            builder.setExpiration(new Date(nowMillis + ttl));
        }
        return builder.compact();
    }

    /**
     * 获取生成token的key
     * 
     * @return
     */
    private static Key getKeyInstance(String key) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(key);
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
        return signingKey;
    }

    /**
     * 解析JWT
     * 
     * @param jwtStr
     * @return
     */
    public Claims parseJWT(String jwtStr) {
        return Jwts.parser().setSigningKey(getKeyInstance(key)).parseClaimsJws(jwtStr).getBody();
    }

    /**
     * 获取用户ID
     * 
     * @return
     */
    public Long getUserId(Claims claims) {
        return Long.parseLong(claims.get("jti").toString());
    }

    /**
     * 刷新TOKEN
     * 
     * @param refreshClaims
     * @param ttl
     * @param refttl
     * @return
     */
    public Map refreshToken(Claims refreshClaims, Long ttl, Long refttl) {
        String id = refreshClaims.getId();
        String subject = refreshClaims.getSubject();
        String roles = refreshClaims.get("roles").toString();
        String headPic = refreshClaims.get("headPic").toString();
        // 重新生成TOKEN
        String accessToken = createJWT(id, subject, headPic, roles, ttl);
        String refreshToken = createJWT(id, subject, headPic, roles, refttl);
        Map tokenMap = new HashMap<>();
        tokenMap.put("accessToken", accessToken);
        tokenMap.put("refreshToken", refreshToken);
        return tokenMap;
    }
}

代码思路:

一。登陆
    前端传入User信息到controller
        调用用户服务查询当前用户
            根据账户查询用户表,
                如果不存在,返回账户密码错误
            获取当前第一个用户
            校验密码,如果该密码为空,或者传进来的用户密码与数据库的密码不一致,不等,返回帐户密码错误
            校验状态,如果查到的用户状态为0,请联系管理员
            查询角色列表,根据用户id查询当前用户拥有多少角色,
                如果角色未空,返回该用户未分配角色
                如果不为空,(可以判断该角色是否满足当前权限,如果不满足,返回权限不足)
            创建authToken map。 
            创建访问TOKEN
            创建刷新TOKEN 
            将访问和刷新token 放入map。
            给查到当前的用户设置刷新时间
            更新用户表
            根据用户id 加载权限列表
        -------------------------------------------------------
                从缓存中获取用户权限列表
                    如果权限为空
                    获取用户的角色
                        如果角色中包含超级管理员,查询所有可用权限                      
                        否则查询用户制定全选
                    将权限放入redis
                    设置过期时间 优化缓存(2小时)
               返回权限 
               -------------------------------------------------------
        如果返回结果为ture
            获取authtoken。
            将访问token设置到相应头中,key,salt,accesstoken,
            将刷新token设置到相应头中,refrekey ,refreshtoken。
    返回结果。  

因为我们用了security 加密密码。所以在设置拦截器的时候,要先放行。security的所有请求。

启动类注入Spring Security的 密码加密

 @Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

/**
 * Security 配置类
 * @ClassName: SecurityConfig
 * @author sans
 * @date 2019年1月11日
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        System.out.println("进入放权所有请求");
        http.authorizeRequests().antMatchers("/**").permitAll().anyRequest().authenticated().and().csrf().disable();
    }
    @Override
    public void configure(WebSecurity web)throws Exception{
        System.out.println("进入放权所有静态页面");
        web.ignoring()
                .antMatchers("**/favicon.ico")
                .antMatchers("**/webjars/**")
                .antMatchers("**/v2**")
                .antMatchers("**/swagger-resources/**")
                .antMatchers("**/resources/**")
                .antMatchers("/swagger-resources/configuration/ui")
                .antMatchers("/swagger-resources")
                .antMatchers("/swagger-resources/configuration/security")
                .antMatchers("**/swagger-ui.html/**");
        System.out.println("进入放权所有静态页面======结束");
    }
}

并添加拦截器

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.qiluodz.interceptor.SyncPermissionInteceptor;
import com.qiluodz.interceptor.WebInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.util.ArrayList;
import java.util.List;

/**
 * 配置类
 * 
 * @ClassName: FastJsonHttpMessageConfig
 * @author xie
 * @date 2019年1月9日
 */
@SpringBootConfiguration
public class FastJsonHttpMessageConfig extends WebMvcConfigurationSupport {

    @Autowired
    private WebInterceptor webInterceptor; //web拦截器

    @Autowired
    private SyncPermissionInteceptor syncPermissionInteceptor; //同步权限拦截器

    /**
     * 配置fastjson
     */
    @Override
    public void configureMessageConverters(List> converters) {
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        // 添加fastJson 的配置信息
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteDateUseDateFormat);
        // 处理中文乱码问题
        List fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        fastConverter.setSupportedMediaTypes(fastMediaTypes);
        // 在convert中添加配置信息.
        fastConverter.setFastJsonConfig(fastJsonConfig);
        // 将convert添加到converters当中
        converters.add(fastConverter);
    }
    /**
     * 配置拦截器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 放行登录注册
        registry.addInterceptor(webInterceptor).addPathPatterns("/**");
        registry.addInterceptor(syncPermissionInteceptor).addPathPatterns("/**");
        // 放行swagger
        registry.addInterceptor(webInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/user/login")
                .excludePathPatterns("**/swagger-resources/**", "**/webjars/**", "**/v2/**", "**/swagger-ui.html");
        registry.addInterceptor(syncPermissionInteceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/user/login")
                .excludePathPatterns("**/swagger-resources/**", "**/webjars/**", "**/v2/**", "**/swagger-ui.html");
    }
    
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("**/swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

}

---------------------------------------------------------------------------------------

web拦截器

import com.alibaba.fastjson.JSONObject;
import com.qiluodz.pojo.vo.DzResult;
import com.qiluodz.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * WEB过滤器
 * 
 * @ClassName: WebInteceptor
 * @author xie
 * @date 2019年1月9日
 * 
 */
@Component
public class WebInterceptor implements HandlerInterceptor {

    private Logger logger = LoggerFactory.getLogger(WebInterceptor.class);

    @Autowired
    private JwtUtil jwtUtil;

    @Value("${auth.key}")
    private String key;

    @Value("${auth.refrekey}")
    private String refrekey;

    @Value("${auth.salt}")
    private String salt;

    @Value("${auth.ttl}")
    private Long ttl;

    @Value("${auth.refrettl}")
    private Long refttl;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        System.out.println("_____进入WebInterceptor_______");

        System.out.println("========当前请求路径为=======");
        System.out.println(request.getRequestURL().toString());

        // 配置跨域
        System.out.println("拦截所有请求");
        System.out.println("设置请求头");
        String origin = request.getHeader("Origin");
        if (origin != null && !"".equals(origin)) {
            System.out.println("获取头,请求头头不等于空");
            System.out.println("开始设置相应头");
            response.setHeader("Access-Control-Allow-Origin", origin);
            response.setHeader("Access-Control-Max-Age", "3600");
            response.addHeader("allowCredentials", "true");
            response.addHeader("Access-Control-Expose-Headers", "Authorization, RefreAuth");
            if (request.getMethod().equalsIgnoreCase("OPTIONS")) {
                System.out.println("请求头中有options,忽略大小写");
                System.out.println("设置响应头的方法");
                response.addHeader("Access-Control-Allow-Methods", "GET,HEAD,POST,PUT,DELETE,TRACE,OPTIONS,PATCH");
                response.addHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization, RefreAuth");
            }
        }
        if (request.getRequestURL().toString().contains("/api/user/login")) {
            System.out.println("访问的是登录页面,放行");
            return true;
        }
        //-----sans
        if (request.getRequestURL().toString().contains("/api/customer/loginByUserName")) {
            System.out.println("2.进入前端登录页面,放行");
            return true;
        }
        if (request.getRequestURL().toString().contains("/swagger")) {
            System.out.println("3.进入SWAGGER-UI.html.放行");
            return true;
        }
        if (request.getRequestURL().toString().contains("/webjars")) {
            System.out.println("3.进入SWAGGER-UI.html.放行");
            return true;
        }
        // 验权
        String token = request.getHeader("Authorization");
        System.out.println("开始验权限");
        Claims claims = null;
        if (StringUtils.isNotBlank(token)) {
            System.out.println("token不等于空");
            System.out.println("token+个盐");
            token = token.substring(salt.length() + 1);
            if (StringUtils.isNotBlank(token)) {
                System.out.println("token加盐后再次判断,不为空");
                try {
                    // 解析token
                    System.out.println("JWT解析Token");
                    claims = jwtUtil.parseJWT(token);
                    request.setAttribute("authInfo", claims);
                    System.out.println("解析成功,授权该请求");
                    return true;
                } catch (Exception e1) {
                    System.out.println("jwt,解析失败");
                    // 验权失败,获取刷新TOKEN
                    System.out.println("开始刷新token,");
                    try {
                        System.out.println("头已经存在,已登录的");
                        String refreToken = request.getHeader("RefreAuth");
                        System.out.println("在请求头中,获取刷新token");
                        Claims refreshClaims = jwtUtil.parseJWT(refreToken);
                        System.out.println("解析刷新头");
                        Map tokenMap = jwtUtil.refreshToken(refreshClaims, ttl, refttl);
                        // 设置请求和响应信息
                        request.setAttribute("authInfo", refreshClaims);
                        System.out.println("授权");
                        System.out.println("获取koken并加盐,然后设置到相应头中");
                        response.setHeader(key, salt + " " + tokenMap.get("accessToken"));
                        System.out.println("获取刷新头,并设置到相应头中");
                        response.setHeader(refrekey, tokenMap.get("refreshToken"));
                        logger.info("TOKEN在拦截器一刷新");
                        System.out.println("__________________________________结束WebInterceptor__________________________________");
                        return true;
                    } catch (Exception e2) {
                        System.out.println("刷新头不存在,首次登陆");
                        e2.printStackTrace();
                    }
                }
            }
        }
        System.out.println("token不存在,或者为空,验签失败");
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        response.getWriter().append(JSONObject.toJSONString(new DzResult().error(2002, "验签失败")));
        return false;
    }

}

---------------------------------------------------------------------------------------

同步权限拦截器

import com.alibaba.fastjson.JSONArray;
import com.qiluodz.exception.AuthenticationException;
import com.qiluodz.pojo.entity.DzUser;
import com.qiluodz.service.managerService.RoleService;
import com.qiluodz.service.managerService.UserService;
import com.qiluodz.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 同步权限拦截器
 * 
 * @ClassName: ReloadPermissionInteceptor
 * @author xie
 * @date 2019年1月15日
 */
@Component
@SuppressWarnings({ "rawtypes", "unchecked" })
public class SyncPermissionInteceptor implements HandlerInterceptor {

    private Logger logger = LoggerFactory.getLogger(SyncPermissionInteceptor.class);

    @Autowired
    private JwtUtil jwtUtil;

    @Value("${auth.ttl}")
    private Long ttl;

    @Value("${auth.refrettl}")
    private Long refttl;

    @Value("${auth.key}")
    private String key;

    @Value("${auth.refrekey}")
    private String refrekey;

    @Value("${auth.salt}")
    private String salt;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Value("${PERMISSION_LIST_KEY}")
    private String permissionListKey;

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("=============进入同步权限拦截器===============");

        System.out.println("========当前请求路径为============");
        System.out.println(request.getRequestURL().toString());
        System.out.println("===========      ===============");

        if (request.getRequestURL().toString().contains("/api/user/login")) {
            System.out.println("1.进入登录页面,放行");
            return true;
        }
        //-----sans
        if (request.getRequestURL().toString().contains("/api/customer/loginByUserName")) {
            System.out.println("2.进入前端登录页面,放行");
            return true;
        }
        if (request.getRequestURL().toString().contains("/swagger")) {
            System.out.println("3.进入SWAGGER-UI.html.放行");
            return true;
        }
        if (request.getRequestURL().toString().contains("/webjars")) {
            System.out.println("3.进入SWAGGER-UI.html.放行");
            return true;
        }
        // 获取当前用户
        Claims claims = (Claims) request.getAttribute("authInfo");
        if (claims!=null){
            System.out.println("2.获取当前用户");
            System.out.println("---------------------------");
            System.out.println("claims:__"+claims);
            System.out.println("___________________________");
        }
        Long uid = Long.parseLong(claims.getId());
        // 查询权限缓存
        String permissionJson = (String) redisTemplate.boundValueOps(permissionListKey + uid).get();
        System.out.println("查询权限缓存");
        if (StringUtils.isBlank(permissionJson)) {
            System.out.println("权限不存在");
            // 重新加载权限
            System.out.println("重新加载权限,获取当前用户的所有权限");
            String loadPermission = userService.loadPermissionByUserId(uid);
            if (StringUtils.isBlank(loadPermission)) {
                System.out.println("权限为空,权限不足");
                throw new AuthenticationException(403, "权限不足");
            }
            // 刷新角色及TOKEN
            DzUser currentUser = userService.findUserById(uid);
            System.out.println("获取最新角色和token");
            if (currentUser == null) {
                System.out.println("用户不存在,权限不足");
                throw new AuthenticationException(403, "权限不足");
            }
            List roles = roleService.findRoleListByUser(uid);
            System.out.println("查询角色表中是否有该用户");
            if (roles == null || roles.size() <= 0) {
                System.out.println("没有.权限不足");
                throw new AuthenticationException(403, "权限不足");
            }
            System.out.println("满足以上条件,创建访问token");
            // 创建访问TOKEN
            String accessToken = jwtUtil.createJWT(currentUser.getId() + "", currentUser.getUsername(),
                    currentUser.getHeadPic(), JSONArray.toJSONString(roles), ttl);
            // 创建刷新TOKEN
            System.out.println("创建刷新token");
            String refreshToken = jwtUtil.createJWT(currentUser.getId() + "", currentUser.getUsername(),
                    currentUser.getHeadPic(), JSONArray.toJSONString(roles), refttl);
            Claims reloadClaims = jwtUtil.parseJWT(accessToken);
            System.out.println("授权访问.");
            request.setAttribute("authInfo", reloadClaims);
            response.setHeader(key, salt + " " + accessToken);
            response.setHeader(refrekey, refreshToken);
            logger.info("TOKEN在拦截器二刷新,用户ID[" + claims.getId() + "] 用户名[" + claims.getSubject() + "]");
        }
        System.out.println("权限存在,放行");
        return true;
    }
}

---------------------------------------------------------------------------------------

创建用户controller

注入请求与相应

@Autowired
private HttpServletResponse response;

@Autowired
private HttpServletRequest request;

@Value("${auth.key}")
private String key;

@Value("${auth.refrekey}")
private String refrekey;

@Value("${auth.salt}")
private String salt;

----------------    用户登陆   -----------------------------------------------------------------------

在登录时,根据用户服务,判断当前用户登录账户及密码正确

/**
 * 用户登录
 * 
 * @param user
 * @return
 */
@PostMapping("/login")
@ApiOperation("用户登录")
@SuppressWarnings("unchecked")
public DzResult login(@RequestBody DzUser user) {
    DzResult result = userService.findUserByUsernameAndPassword(user);
    if (result.getFlag() == true) {
        Map authToken = (Map) result.getData();
        String accessToken = authToken.get("accessToken");
        String refreshToken = authToken.get("refreshToken");
        response.setHeader(key, salt + " " + accessToken);
        response.setHeader(refrekey, refreshToken);
        result.setData(null);
    }
    return result;
}
@Override
public DzResult findUserByUsernameAndPassword(DzUser user) {
    DzUserExample example = new DzUserExample();
    Criteria criteria = example.createCriteria();
    criteria.andUsernameEqualTo(user.getUsername());
    List userList = userMapper.selectByExample(example);
    if (userList == null || userList.size() <= 0) {
        return new DzResult().error(StatusCode.LOGIN_ERROR, "用户名或密码错误");
    }
    DzUser existUser = userList.get(0);
    // 校验密码
    if (StringUtils.isBlank(user.getPassword())
            || !passwordEncoder.matches(user.getPassword(), existUser.getPassword())) {
        return new DzResult().error(StatusCode.LOGIN_ERROR, "用户名或密码错误");
    }
    // 校验状态
    // 状态 1:正常使用 0:禁用
    if (existUser.getStatus().equals("0")) {
        return new DzResult().error(StatusCode.LOGIN_USER_PROHIBIT, "账户已被禁用,请联系管理员");
    }
    // 查询角色列表
    List roles = roleMapper.findRolesByUser(existUser.getId());
    if (roles == null || roles.size() <= 0) {
        return new DzResult().error(StatusCode.LOGIN_ROLE_NONE, "用户未分配角色");
    } else {
        if (roles.contains("MANUFACTURER") || roles.contains("SURVEYOR") ) {
            System.out.println("该账户权限不足,请联系客服");
            throw new AuthenticationException(403, "权限不足,该账户是厂商/量体,请联系客服");
        }
    }
    
    Map authToken = new HashMap<>();
    // 创建访问TOKEN
    String accessToken = jwtUtil.createJWT(existUser.getId() + "", existUser.getUsername(), existUser.getHeadPic(),
            JSONArray.toJSONString(roles), ttl);
    // 创建刷新TOKEN
    String refreshToken = jwtUtil.createJWT(existUser.getId() + "", existUser.getUsername(), existUser.getHeadPic(),
            JSONArray.toJSONString(roles), refttl);
    authToken.put("accessToken", accessToken);
    authToken.put("refreshToken", refreshToken);
    // 刷新登录时间
    existUser.setLoginTime(new Date());
    userMapper.updateByPrimaryKey(existUser);
    // 加载权限列表
    loadPermissionByUserId(existUser.getId());
    return new DzResult().success(authToken);
}

--------------------------------------------------------------------------

userRoleMapper


--------------------------------------------------------------------------

rolerMapper


--------------------------------------------------------------------------

PermissionMapper


 
 
 
 
 
 
 
 
 
 

--------------------------------------------------------------------------

RolePermissionMapper

 

--------------------------------------------------------------------------

代码思路  -- 添加用户 

      密码加密,补全属性,设置头像

      关联角色信息,如果用户传过来的角色id为空,抛异常,绑定错误

             切割所有角色id,便利

                    创建关联对象,设置角色id & 设置用户id,插入关联对象表

 代码思路 - - 更新用户

      查到当前用户,

      更新用户信息,执行更新

      获取用户所有角色ID , 如果角色id为空,授权失败

      查找已存在的用户id的绑定的所有角色  清空角色,

      获取,当前更新的用户的 所有角色.

      便利获取每个角色id,  

      创建用户角色关联对象,

       设置用户id和角色id .

       插入角色表,

       调用清除权限缓存

代码思路 - - 删除用户

       获取删除用户的 id集合

       便利,获取每一个用户

       设置伪删除,设置更新时间

        更新.

       调用清除权限缓存 

--------------------------------------------------------------------------------------------------------------------------

 

 

 

你可能感兴趣的:(JWT)