package com.doumee.config.jwt; import com.alibaba.fastjson.JSONObject; import com.doumee.core.annotation.LoginRequired; import com.doumee.core.annotation.LoginShopRequired; import com.doumee.core.constants.Constants; import com.doumee.core.constants.ResponseStatus; import com.doumee.core.exception.BusinessException; import com.doumee.dao.business.model.Member; import com.doumee.dao.business.model.ShopInfo; import io.jsonwebtoken.JwtException; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.web.client.RestTemplate; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Objects; @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Autowired private JdbcTemplate dao; @Autowired private RedisTemplate redisTemplate; /** * 添加拦截器 */ @Override public void addInterceptors(InterceptorRegistry registry) { //API接口JwtToken拦截器 HandlerInterceptor TokenInterceptor = new HandlerInterceptor() { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 如果不是映射到方法直接通过 if (!(handler instanceof HandlerMethod)) { return true; } HandlerMethod handlerMethod = (HandlerMethod) handler; Class beanType = handlerMethod.getBeanType(); // 有 @LoginRequired 注解,需要登录认证 if (beanType.isAnnotationPresent(LoginRequired.class)) { //获取token String token = request.getHeader(JwtTokenUtil.HEADER_KEY); // 从 http 请求头中取出 token if (StringUtils.isNotBlank(token)) { checkMemberLogin(request,response); } else { throw new BusinessException(ResponseStatus.BE_OVERDUE.getCode(),"未登录"); } }else if (handlerMethod.hasMethodAnnotation(LoginRequired.class)){ //获取token String token = request.getHeader(JwtTokenUtil.HEADER_KEY); // 从 http 请求头中取出 token if (StringUtils.isNotBlank(token)) { checkMemberLogin(request,response); } else { throw new BusinessException(ResponseStatus.BE_OVERDUE.getCode(),"未登录"); } }else if (beanType.isAnnotationPresent(LoginShopRequired.class)) { //获取token String token = request.getHeader(JwtTokenUtil.HEADER_KEY); // 从 http 请求头中取出 token if (StringUtils.isNotBlank(token)) { checkShopLogin(request,response); } else { throw new BusinessException(ResponseStatus.BE_OVERDUE.getCode(),"未登录"); } }else if (handlerMethod.hasMethodAnnotation(LoginShopRequired.class)){ //获取token String token = request.getHeader(JwtTokenUtil.HEADER_KEY); // 从 http 请求头中取出 token if (StringUtils.isNotBlank(token)) { checkShopLogin(request,response); } else { throw new BusinessException(ResponseStatus.BE_OVERDUE.getCode(),"未登录"); } } return true; } }; registry.addInterceptor(TokenInterceptor).addPathPatterns("/web/**"); } public Boolean checkMemberLogin(HttpServletRequest request, HttpServletResponse response){ String token = request.getHeader(JwtTokenUtil.HEADER_KEY); try { if(!token.startsWith(Constants.ZERO+"")){ throw new BusinessException(ResponseStatus.TOKEN_EXCEED_TIME); } String tokenRedis = (String) redisTemplate.opsForValue().get(token); if(StringUtils.isBlank(tokenRedis)){ throw new BusinessException(ResponseStatus.BE_OVERDUE); } Member member = JSONObject.parseObject(tokenRedis, Member.class); if(Objects.isNull(member)){ throw new BusinessException(ResponseStatus.TOKEN_EXCEED_TIME); } Integer isDeleted = dao.queryForObject(" select COALESCE(DELETED,1) from member where id = ?", Integer.class, member.getId()); if(isDeleted.equals(Constants.ONE)){ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"用户已删除,请联系管理员"); } Integer count = dao.queryForObject("select count(1) from member where id = ?", Integer.class, member.getId()); if (count != null && count > 0) { request.setAttribute(JwtTokenUtil.MEMBER_INFO, JSONObject.toJSONString(member)); request.setAttribute(JwtTokenUtil.MEMBER_ID, member.getId()); return true; }else{ throw new BusinessException(ResponseStatus.BE_OVERDUE.getCode(),"用户信息出错"); } } catch (IllegalArgumentException | JwtException e) { throw new BusinessException(ResponseStatus.BE_OVERDUE.getCode(),"未登录"); } } public Boolean checkShopLogin(HttpServletRequest request, HttpServletResponse response){ String token = request.getHeader(JwtTokenUtil.HEADER_KEY); try { if(!token.startsWith(Constants.TWO+"")){ throw new BusinessException(ResponseStatus.TOKEN_EXCEED_TIME); } String tokenRedis = (String) redisTemplate.opsForValue().get(token); if(StringUtils.isBlank(tokenRedis)){ throw new BusinessException(ResponseStatus.BE_OVERDUE); } ShopInfo shop = JSONObject.parseObject(tokenRedis, ShopInfo.class); if(Objects.isNull(shop)){ throw new BusinessException(ResponseStatus.BE_OVERDUE); } String openid = shop.getOpenid(); Integer shopId = getTokenId(token); Integer isDeleted = dao.queryForObject(" select COALESCE(ISDELETED,0) from shop_info where id = ?", Integer.class, shopId); if(isDeleted== Constants.ONE){ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"商户已删除,请联系管理员"); } Integer isForbidden = dao.queryForObject(" select COALESCE(STATUS,0) from shop_info where id = ?", Integer.class, shopId); if(isForbidden == Constants.ONE){ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"商户已禁用,请联系管理员"); } String dbOpenid = dao.queryForObject(" select ifnull(openid,'') from shop where id = ?", String.class, shopId); if(StringUtils.isBlank(dbOpenid)||!openid.equals(dbOpenid)){ throw new BusinessException(ResponseStatus.TOKEN_EXCEED_TIME); } Integer count = dao.queryForObject("select count(1) from shop where id = ?", Integer.class, shopId); if (count != null && count > 0) { request.setAttribute(JwtTokenUtil.SHOP_INFO, JSONObject.toJSONString(shop)); request.setAttribute(JwtTokenUtil.SHOP_ID, shop.getId()); return true; }else{ throw new BusinessException(ResponseStatus.BE_OVERDUE.getCode(),"用户信息出错"); } } catch (IllegalArgumentException | JwtException e) { throw new BusinessException(ResponseStatus.BE_OVERDUE); } } public Integer getTokenId(String token){ try { Integer lastIndex = token.lastIndexOf("_")+1; Integer tokenId = Integer.valueOf(token.substring(lastIndex)); return tokenId; }catch (Exception e){ throw new BusinessException(ResponseStatus.BE_OVERDUE); } } @Bean public RestTemplate getRestTemplate(){ return new RestTemplate(); } }