| package com.doumee.config.jwt; | 
|   | 
| import com.alibaba.fastjson.JSONObject; | 
| import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; | 
| import com.doumee.biz.system.SystemDictDataBiz; | 
| import com.doumee.service.business.third.model.LoginUserInfo; | 
| import com.doumee.core.utils.Constants; | 
| import com.doumee.core.utils.HttpsUtil; | 
| import com.doumee.dao.system.SystemUserMapper; | 
| import com.doumee.dao.system.model.SystemUser; | 
| import io.jsonwebtoken.Jwts; | 
| import io.jsonwebtoken.SignatureAlgorithm; | 
| import lombok.extern.slf4j.Slf4j; | 
| import org.apache.commons.lang3.StringUtils; | 
| import org.apache.http.HttpEntity; | 
| import org.apache.http.HttpResponse; | 
| import org.apache.http.client.HttpClient; | 
| import org.apache.http.client.methods.HttpGet; | 
| import org.apache.http.impl.client.HttpClientBuilder; | 
| import org.apache.http.util.EntityUtils; | 
| import org.springframework.beans.factory.annotation.Autowired; | 
| import org.springframework.data.redis.core.RedisTemplate; | 
| import org.springframework.stereotype.Component; | 
|   | 
| import javax.annotation.Resource; | 
| import java.io.IOException; | 
| import java.util.Date; | 
| import java.util.HashMap; | 
| import java.util.Map; | 
| import java.util.concurrent.TimeUnit; | 
|   | 
| @Component | 
| @Slf4j | 
| public class JwtTokenUtil { | 
|   | 
|     @Autowired | 
|     private RedisTemplate<String,Object> redisTemplate; | 
|     @Resource | 
|     private JwtProperties jwtProperties; | 
|     @Autowired | 
|     private SystemDictDataBiz systemDictDataBiz ; | 
|     @Autowired | 
|     private SystemUserMapper systemUserMapper; | 
|     /** | 
|      * 生成token令牌 | 
|      * | 
|      * @param payloads 令牌中携带的附加信息 | 
|      * @return 令token牌 | 
|      */ | 
|     public String generateToken( LoginUserInfo payloads) { | 
|         if(payloads == null){ | 
|             return  null; | 
|         } | 
|         payloads.setLoginDate(new Date()); | 
|         Map<String,Object> map = new HashMap<>(); | 
|         map.put("id",payloads.getId()); | 
| //        Map<String,Object> map =   BeanUtil.beanToMap(payloads); | 
|         return generateTokenDo(payloads); | 
|     } | 
|   | 
|     /** | 
|      * 从令牌中获取用户名 | 
|      * | 
|      * @param token 令牌 | 
|      * @return 用户名 | 
|      */ | 
|     public String getUsernameFromToken(String token) { | 
|         String username; | 
|         try { | 
|             LoginUserInfo claims = getClaimsFromToken(token); | 
|             username = claims.getUsername(); | 
|         } catch (Exception e) { | 
|             username = null; | 
|         } | 
|         return username; | 
|     } | 
|     public LoginUserInfo getUserInfoByToken(String token) { | 
|         try { | 
|             LoginUserInfo claims = getClaimsFromToken(token); | 
|             return claims; | 
|         } catch (Exception e) { | 
|            e.printStackTrace(); | 
|         } | 
|         return null; | 
|     } | 
|   | 
|     /** | 
|      * 判断令牌是否过期 | 
|      * | 
|      * @param token 令牌 | 
|      * @return 是否过期 | 
|      */ | 
|     public Boolean isTokenExpired(String token) { | 
|         try { | 
|             LoginUserInfo claims = getClaimsFromToken(token); | 
|             Date expiration = //claims.getLoginDate(); | 
|             new Date(claims.getLoginDate().getTime() + jwtProperties.getExpiration()); | 
|             return expiration.before(new Date()); | 
|         } catch (Exception e) { | 
|             //验证JWT签名失败等同于令牌过期 | 
|             return true; | 
|         } | 
|     } | 
|   | 
|     /** | 
|      * 刷新令牌 | 
|      * | 
|      * @param token 原令牌 | 
|      * @return 新令牌 | 
|      */ | 
|     public String refreshToken(String token) { | 
|         String refreshedToken; | 
|         try { | 
|             LoginUserInfo claims = getClaimsFromToken(token); | 
|             claims.setLoginDate(new Date()); | 
|             refreshedToken = generateTokenDo(claims); | 
|             if(refreshedToken!=null){ | 
|                 redisTemplate.delete(Constants.REDIS_TOKEN_KEY+token);//删除老的token | 
|             } | 
|         } catch (Exception e) { | 
|             refreshedToken = null; | 
|         } | 
|         return refreshedToken; | 
|     } | 
|     /** | 
|      * 退出登陆 | 
|      * | 
|      * @param token 原令牌 | 
|      * @return 新令牌 | 
|      */ | 
|     public void logout(String token) { | 
|         try { | 
|             //登出海康系统数据 | 
|             LoginUserInfo loginUserInfo = this.getUserInfoByToken(token); | 
|             String url = systemDictDataBiz.queryByCode(Constants.HK_PARAM,Constants.HK_HTTPS).getCode() + | 
|                     systemDictDataBiz.queryByCode(Constants.HK_PARAM,Constants.HK_HOST).getCode() + | 
|                     systemDictDataBiz.queryByCode(Constants.HK_PARAM,Constants.LOGIN_OUT_URL).getCode(); | 
|             if(StringUtils.isNotBlank(loginUserInfo.getHkMenuToken())){ | 
|                 log.info("调起海康退出登录=======================>"+url+"?token="+loginUserInfo.getHkMenuToken()); | 
| //                this.hkLoginOut(url+"?token="+loginUserInfo.getHkMenuToken()); | 
|                 HttpsUtil.get(url+"?token="+loginUserInfo.getHkMenuToken(),true); | 
|             } | 
|             //删除老的token | 
|             redisTemplate.delete(Constants.REDIS_TOKEN_KEY+token); | 
|         } catch (Exception e) { | 
|             e.printStackTrace(); | 
|         } | 
|     } | 
|   | 
|     public void logoutForH5(String token) { | 
|         try { | 
|             //登出海康系统数据 | 
|             LoginUserInfo loginUserInfo = this.getUserInfoByToken(token); | 
|             //删除老的token | 
|             redisTemplate.delete(Constants.REDIS_TOKEN_KEY+token); | 
|             systemUserMapper.update(null,new UpdateWrapper<SystemUser>().lambda().set(SystemUser::getOpenid,null) | 
|                     .eq(SystemUser::getId,loginUserInfo.getId())); | 
|   | 
|         } catch (Exception e) { | 
|             e.printStackTrace(); | 
|         } | 
|     } | 
|     public void hkLoginOut(String url){ | 
|         try { | 
|             // 创建HttpClient对象 | 
|             HttpClient httpClient = HttpClientBuilder.create().build(); | 
|             // 创建HttpGet对象,指定要访问的URL地址 | 
|             HttpGet httpGet = new HttpGet(url); | 
|             // 发送GET请求,获取响应 | 
|             HttpResponse response = httpClient.execute(httpGet); | 
|             // 获取响应状态码 | 
|             int statusCode = response.getStatusLine().getStatusCode(); | 
|             // 判断请求是否成功 | 
|             if (statusCode == 200) { | 
|                 // 获取响应内容 | 
|                 HttpEntity entity = response.getEntity(); | 
|                 String responseContent = EntityUtils.toString(entity, "UTF-8"); | 
|                 System.out.println(responseContent); | 
|                 log.info("调起海康退出登录返回信息=======================>"+responseContent); | 
|             } else { | 
|                 System.out.println("请求失败,响应码:" + statusCode); | 
|             } | 
|         } catch (IOException e) { | 
|             e.printStackTrace(); | 
|         } | 
|     } | 
|   | 
|   | 
|     /** | 
|      * 验证令牌 | 
|      * | 
|      * @param token       令牌 | 
|      * @param userId  用户Id用户名 | 
|      * @return 是否有效 | 
|      */ | 
|     public Boolean validateToken(String token, String userId) { | 
|   | 
|         String username = getUsernameFromToken(token); | 
|         return (username.equals(userId) && !isTokenExpired(token)); | 
|     } | 
|   | 
|   | 
|     /** | 
|      * 从claims生成令牌,如果看不懂就看谁调用它 | 
|      * | 
|      * @return 令牌 | 
|      */ | 
|     private String generateTokenDo(LoginUserInfo userInfo) { | 
|         Map<String, Object> claims = new HashMap<>(); | 
|         claims.put("id",userInfo.getId()); | 
|         Date expirationDate = new Date(System.currentTimeMillis() + jwtProperties.getExpiration()); | 
|         String token = Jwts.builder().setClaims(claims) | 
|                 .setExpiration(expirationDate) | 
|                 .signWith(SignatureAlgorithm.HS512, jwtProperties.getSecret()) | 
|                 .compact(); | 
|         redisTemplate.opsForValue().set(Constants.REDIS_TOKEN_KEY+token,JSONObject.toJSONString(userInfo),jwtProperties.getExpiration(), TimeUnit.MILLISECONDS); | 
|         return token; | 
|     } | 
|   | 
|   | 
|     /** | 
|      * 从令牌中获取数据声明,验证JWT签名 | 
|      * | 
|      * @param token 令牌 | 
|      * @return 数据声明 | 
|      */ | 
|     private LoginUserInfo getClaimsFromToken(String token) { | 
|         LoginUserInfo claims; | 
|         try { | 
|             String userInfo = (String) redisTemplate.opsForValue().get(Constants.REDIS_TOKEN_KEY+token); | 
|             claims = JSONObject.toJavaObject(JSONObject.parseObject(userInfo),LoginUserInfo.class); | 
|             refreshTokenTime(token); | 
|         } catch (Exception e) { | 
|             claims = null; | 
|         } | 
|         return claims; | 
|     } | 
|   | 
|     /** | 
|      * 向后延伸有效期保持会话继续 | 
|      * @param token | 
|      */ | 
|     public void refreshTokenTime(String token ) { | 
|         log.error("===============开始刷新登录token"+token); | 
|         redisTemplate.expire(Constants.REDIS_TOKEN_KEY+token,jwtProperties.getExpiration(), TimeUnit.MILLISECONDS); | 
|         log.error("===============结束刷新登录token"+token); | 
| //        redisTemplate.opsForValue().set(Constants.REDIS_TOKEN_KEY+token,usrerInfo,jwtProperties.getExpiration(), TimeUnit.MILLISECONDS); | 
|     } | 
| } |