pms-parent/pms-web-wechat/pom.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
pms-parent/pms-web-wechat/src/main/java/com/dy/pmsWechat/login/AuthController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
pms-parent/pms-web-wechat/src/main/java/com/dy/pmsWechat/login/WeChatService.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
pms-parent/pms-web-wechat/src/main/java/com/dy/pmsWechat/util/JwtUtil.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
pms-parent/pms-web-wechat/src/main/resources/application.yml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
pms-parent/pom.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
pms-parent/pms-web-wechat/pom.xml
@@ -201,6 +201,11 @@ <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>${jjwt.version}</version> </dependency> </dependencies> <build> pms-parent/pms-web-wechat/src/main/java/com/dy/pmsWechat/login/AuthController.java
@@ -21,7 +21,7 @@ public BaseResponse<Boolean> login(@RequestBody QueryVo vo) { try { JSONObject wxResponse = weChatService.login(vo.code); if (wxResponse.containsKey("openid")) { if (wxResponse.containsKey("token")) { // 成功获取到了用户的openid,session_key和其他信息 // 这里可以进行更多业务逻辑操作,例如生成自定义token返回给客户端 return BaseResponseUtils.buildSuccess(wxResponse); pms-parent/pms-web-wechat/src/main/java/com/dy/pmsWechat/login/WeChatService.java
@@ -3,12 +3,14 @@ import com.alibaba.fastjson2.JSONObject; import com.dy.pmsGlobal.daoMp.MpOpenIdMapper; import com.dy.pmsGlobal.pojoMp.MpOpenId; import com.dy.pmsWechat.util.JwtUtil; import com.dy.pmsWechat.util.RestTemplateUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.io.IOException; import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -23,6 +25,12 @@ @Value("${wechat.loginUrl}") private String loginUrl; @Value("${wechat.jwt.secret-key}") private String secretKey; @Value("${wechat.jwt.ttl}") private long ttlMillis; private final RestTemplateUtil restTemplateUtil; private MpOpenIdMapper mpOpenIdDao; @@ -44,21 +52,21 @@ queryParams.put("grant_type", "authorization_code"); Map<String, String> headerParams = new HashMap<>(); JSONObject wxMpUser = restTemplateUtil.get(loginUrl, queryParams, headerParams); String openId = wxMpUser.get("openid").toString(); //获取微信信息添加到数据库 //先根据openid查询用户信息 MpOpenId userInfo = mpOpenIdDao.getInfoByOpenId(wxMpUser.get("openid").toString()); MpOpenId userInfo = mpOpenIdDao.getInfoByOpenId(openId); if(userInfo == null){ //数据库没有时添加到数据库中 userInfo = new MpOpenId(); userInfo.setOpenId(wxMpUser.get("openid").toString()); userInfo.setOpenId(openId); userInfo.setCreateTime(new Date()); mpOpenIdDao.insert(userInfo); } //授权完成之后,跳转到具体的功能页面 //生成token,按照一定规则生成字符串,可以包含用户信息 String token= JwtHelper.createToken(userInfo.getId(),userInfo.getNickName()); //localhost:8080/weixin?a=1&token=222 if(returnUrl.indexOf("?")==-1){//若returnUrl中没有参数 return "redirect:"+returnUrl+"?token="+token; }else{ return "redirect:"+returnUrl+"&token="+token; } //登陆controller中生成,返回给客户端 Map<String, Object> claims = new HashMap<>(); claims.put("openId",openId); String token = JwtUtil.createJwt(secretKey,ttlMillis,claims); return new JSONObject().fluentPut("token",token); } } pms-parent/pms-web-wechat/src/main/java/com/dy/pmsWechat/util/JwtUtil.java
@@ -1,46 +1,70 @@ package com.dy.pmsWechat.util; import cn.hutool.jwt.Claims; import com.alibaba.druid.util.StringUtils; import io.jsonwebtoken.*; import io.jsonwebtoken.security.Keys; import javax.crypto.SecretKey; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.Map; public class JwtUtil { //token字符串有效时间 private static long tokenExpiration = 24*60*60*1000; //加密编码秘钥 private static String tokenSignKey = "123456"; //根据userid 和 username 生成token字符串 public static String createToken(Long userId, String userName) { String token = Jwts.builder() //设置token分类 .setSubject("GGKT-USER") //token字符串有效时长 .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration)) //私有部分(用户信息) .claim("userId", userId) .claim("userName", userName) //根据秘钥使用加密编码方式进行加密,对字符串压缩 .signWith(SignatureAlgorithm.HS512, tokenSignKey) .compressWith(CompressionCodecs.GZIP) .compact(); return token; /** * 生成jwt * 使用Hs256算法, 私匙使用固定秘钥 * * @param secretKey jwt秘钥 * @param ttlMillis jwt过期时间(毫秒) * @param claims 设置的信息 * @return */ public static String createJwt(String secretKey, long ttlMillis, Map<String, Object> claims) { // 指定签名的时候使用的签名算法,也就是header那部分 // SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; // 生成JWT的时间 long expMillis = System.currentTimeMillis() + ttlMillis; Date exp = new Date(expMillis); //生成 HMAC 密钥,根据提供的字节数组长度选择适当的 HMAC 算法,并返回相应的 SecretKey 对象。 SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8)); // 设置jwt的body JwtBuilder builder = Jwts.builder() // 设置签名使用的签名算法和签名使用的秘钥 .signWith(key) // 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的 .claims(claims) // 设置过期时间 .expiration(exp); return builder.compact(); } //从token字符串获取userid public static Long getUserId(String token) { if(StringUtils.isEmpty(token)) return null; Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token); Claims claims = claimsJws.getBody(); Integer userId = (Integer)claims.get("userId"); return userId.longValue(); } /** * Token解密 * * @param secretKey jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个 * @param token 加密后的token * @return */ public static Claims parseJWT(String secretKey, String token) { //从token字符串获取getUserName public static String getUserName(String token) { if(StringUtils.isEmpty(token)) return ""; Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token); Claims claims = claimsJws.getBody(); return (String)claims.get("userName"); //生成 HMAC 密钥,根据提供的字节数组长度选择适当的 HMAC 算法,并返回相应的 SecretKey 对象。 SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8)); // 得到DefaultJwtParser JwtParser jwtParser = Jwts.parser() // 设置签名的秘钥 .verifyWith(key) .build(); Jws<Claims> jws = jwtParser.parseSignedClaims(token); Claims claims = jws.getPayload(); return claims; } } pms-parent/pms-web-wechat/src/main/resources/application.yml
@@ -16,4 +16,7 @@ wechat: appId: wx2e6beb0eca7c3672 appSecret: b8f8ce34e13d3ba2eeaeba89068d7fbe loginUrl: https://api.weixin.qq.com/sns/jscode2session loginUrl: https://api.weixin.qq.com/sns/jscode2session jwt: secret-key: dayuzhuisu123456789abcdefghigklmnopqrstuvwxyz ttl: 7200000 pms-parent/pom.xml
@@ -52,6 +52,8 @@ <mapstruct.version>1.5.5.Final</mapstruct.version> <dubbo.version>3.2.11</dubbo.version> <hutool-all.version>5.8.22</hutool-all.version> <jjwt.version>0.12.6</jjwt.version> <jdom2.version>2.0.6.1</jdom2.version> <quartz.version>2.1.7</quartz.version> <junit.version>4.13.2</junit.version> @@ -365,7 +367,14 @@ <type>pom</type> <scope>import</scope> </dependency> <!--JWT令牌--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>${jjwt.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- 测试 --> <dependency> <groupId>junit</groupId>