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<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); 
 | 
        } catch (Exception e) { 
 | 
            claims = null; 
 | 
        } 
 | 
        return claims; 
 | 
    } 
 | 
} 
 |