SysLoginController.java 7.4 KB

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