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.core.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 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 map = new HashMap<>(); map.put("id",payloads.getId()); // Map 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().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 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); } catch (Exception e) { claims = null; } return claims; } }