SysLoginController.java 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. package com.zhentao.web.controller.system;
  2. import com.alibaba.fastjson2.JSON;
  3. import com.alibaba.fastjson2.JSONObject;
  4. import com.zhentao.common.config.WxAppConfig;
  5. import com.zhentao.common.constant.Constants;
  6. import com.zhentao.common.core.domain.AjaxResult;
  7. import com.zhentao.common.core.domain.entity.SysMenu;
  8. import com.zhentao.common.core.domain.entity.SysUser;
  9. import com.zhentao.common.core.domain.model.LoginBody;
  10. import com.zhentao.common.core.domain.model.LoginUser;
  11. import com.zhentao.common.core.domain.model.WxLoginBody;
  12. import com.zhentao.common.utils.SecurityUtils;
  13. import com.zhentao.common.utils.StringUtils;
  14. import com.zhentao.common.utils.sign.Base64;
  15. import com.zhentao.framework.web.service.SysLoginService;
  16. import com.zhentao.framework.web.service.SysPermissionService;
  17. import com.zhentao.framework.web.service.TokenService;
  18. import com.zhentao.system.service.ISysMenuService;
  19. import org.slf4j.Logger;
  20. import org.slf4j.LoggerFactory;
  21. import org.springframework.beans.factory.annotation.Autowired;
  22. import org.springframework.web.bind.annotation.GetMapping;
  23. import org.springframework.web.bind.annotation.PostMapping;
  24. import org.springframework.web.bind.annotation.RequestBody;
  25. import org.springframework.web.bind.annotation.RestController;
  26. import org.springframework.web.client.RestTemplate;
  27. import javax.crypto.Cipher;
  28. import javax.crypto.spec.IvParameterSpec;
  29. import javax.crypto.spec.SecretKeySpec;
  30. import java.security.spec.AlgorithmParameterSpec;
  31. import java.util.Arrays;
  32. import java.util.List;
  33. import java.util.Set;
  34. /**
  35. * 登录验证
  36. *
  37. * @author ruoyi
  38. */
  39. @RestController
  40. public class SysLoginController
  41. {
  42. @Autowired
  43. private SysLoginService loginService;
  44. @Autowired
  45. private ISysMenuService menuService;
  46. @Autowired
  47. private SysPermissionService permissionService;
  48. @Autowired
  49. private TokenService tokenService;
  50. @Autowired
  51. private RestTemplate restTemplate;
  52. @Autowired
  53. private WxAppConfig wxAppConfig;
  54. private static final Logger logger = LoggerFactory.getLogger(SysLoginController.class);
  55. @PostMapping("/wxLogin")
  56. public AjaxResult wxLogin(@RequestBody WxLoginBody wxLoginBody){
  57. logger.info("登录参数: " + JSON.toJSONString(wxLoginBody));
  58. // 获取登录凭证, 只能用一次
  59. String code = wxLoginBody.getCode();
  60. // 密钥
  61. String encryptedIv = wxLoginBody.getEncryptedIv();
  62. // 加密数据
  63. String encryptedData = wxLoginBody.getEncryptedData();
  64. // 向微信服务器发送请求获取用户信息
  65. String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + wxAppConfig.getAppId() +
  66. "&secret=" + wxAppConfig.getAppSecret() + "&js_code=" + code + "&grant_type=authorization_code";
  67. String res = restTemplate.getForObject(url, String.class);
  68. JSONObject jsonObject = JSONObject.parseObject(res);
  69. // 获取session_key和openid
  70. String sessionKey = jsonObject.getString("session_key");
  71. String openid = jsonObject.getString("openid");
  72. // 解密
  73. String decryptResult = "";
  74. // 如果没有绑定微信开发平台, 解析结果是没有unionid的
  75. try {
  76. decryptResult = decrypt(sessionKey, encryptedIv, encryptedData);
  77. } catch (Exception e) {
  78. e.printStackTrace();
  79. return AjaxResult.error("微信登录失败");
  80. }
  81. if(StringUtils.hasText(decryptResult)){
  82. // 如果解析成功, 获取token
  83. String token = loginService.wxLogin(decryptResult);
  84. AjaxResult ajax = AjaxResult.success();
  85. ajax.put(Constants.TOKEN, token);
  86. return ajax;
  87. }else{
  88. return AjaxResult.error("微信登录失败");
  89. }
  90. }
  91. /**
  92. * AES解密
  93. * @param sessionKey
  94. * @param encryptedIv
  95. * @param encryptedData
  96. * @return
  97. * @throws Exception
  98. */
  99. private String decrypt(String sessionKey, String encryptedIv, String encryptedData) throws Exception {
  100. // 转化为字节数组
  101. byte[] key = Base64.decode(sessionKey);
  102. byte[] iv = Base64.decode(encryptedIv);
  103. byte[] encData = Base64.decode(encryptedData);
  104. // 如果密钥不足16位, 那么久补足
  105. int base = 16;
  106. if (key.length % base != 0)
  107. {
  108. int groups = key.length / base + (key.length % base != 0 ? 1 : 0);
  109. byte[] temp = new byte[groups * base];
  110. Arrays.fill(temp, (byte) 0);
  111. System.arraycopy(key, 0, temp, 0, key.length);
  112. key = temp;
  113. }
  114. // 如果初始向量不足16位, 也补足
  115. if(iv.length % base != 0){
  116. int groups = iv.length / base + (iv.length % base != 0 ? 1 : 0);
  117. byte[] temp = new byte[groups * base];
  118. Arrays.fill(temp, (byte) 0);
  119. System.arraycopy(iv, 0, temp, 0, iv.length);
  120. iv = temp;
  121. }
  122. AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
  123. String resultStr = null;
  124. try {
  125. Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
  126. SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
  127. cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
  128. resultStr = new String(cipher.doFinal(encData), "UTF-8");
  129. } catch (Exception e) {
  130. logger.info("解析错误");
  131. e.printStackTrace();
  132. }
  133. // 解析解密后的字符串
  134. return resultStr;
  135. }
  136. /**
  137. * 登录方法
  138. *
  139. * @param loginBody 登录信息
  140. * @return 结果
  141. */
  142. @PostMapping("/login")
  143. public AjaxResult login(@RequestBody LoginBody loginBody)
  144. {
  145. AjaxResult ajax = AjaxResult.success();
  146. // 生成令牌
  147. String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
  148. loginBody.getUuid());
  149. ajax.put(Constants.TOKEN, token);
  150. return ajax;
  151. }
  152. /**
  153. * 获取用户信息
  154. *
  155. * @return 用户信息
  156. */
  157. @GetMapping("getInfo")
  158. public AjaxResult getInfo()
  159. {
  160. LoginUser loginUser = SecurityUtils.getLoginUser();
  161. if (loginUser == null) {
  162. return AjaxResult.error("未获取到登录用户信息");
  163. }
  164. SysUser user = loginUser.getUser();
  165. // 角色集合
  166. Set<String> roles = permissionService.getRolePermission(user);
  167. // 权限集合
  168. Set<String> permissions = permissionService.getMenuPermission(user);
  169. if (loginUser.getPermissions() != null && !loginUser.getPermissions().equals(permissions))
  170. {
  171. loginUser.setPermissions(permissions);
  172. tokenService.refreshToken(loginUser);
  173. }
  174. AjaxResult ajax = AjaxResult.success();
  175. ajax.put("user", user);
  176. ajax.put("roles", roles);
  177. ajax.put("permissions", permissions);
  178. return ajax;
  179. }
  180. /**
  181. * 获取路由信息
  182. *
  183. * @return 路由信息
  184. */
  185. @GetMapping("getRouters")
  186. public AjaxResult getRouters()
  187. {
  188. Long userId = SecurityUtils.getUserId();
  189. List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
  190. return AjaxResult.success(menuService.buildMenus(menus));
  191. }
  192. }