package com.epmet.controller; import com.epmet.commons.tools.annotation.LoginUser; import com.epmet.commons.tools.exception.ErrorCode; import com.epmet.commons.tools.security.dto.TokenDto; import com.epmet.commons.tools.utils.Result; import com.epmet.commons.tools.validator.AssertUtils; import com.epmet.commons.tools.validator.ValidatorUtils; import com.epmet.dto.form.LoginByPassWordFormDTO; import com.epmet.dto.form.LoginByWxCodeFormDTO; import com.epmet.dto.form.ResiWxPhoneFormDTO; import com.epmet.dto.result.UserTokenResultDTO; import com.epmet.service.CaptchaService; import com.epmet.service.LoginService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.imageio.ImageIO; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.awt.image.BufferedImage; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; /** * @Description 通用登录接口 * @Author yinzuomei * @Date 2020/3/14 13:58 */ @Slf4j @RestController @RequestMapping("login") public class LoginController { @Autowired private CaptchaService captchaService; @Autowired private LoginService loginService; /** * @return void * @param response * @param uuid * @Author yinzuomei * @Description 运营端管理后台-生成验证码 * @Date 2020/3/17 16:08 **/ @GetMapping("captcha") public void captcha(HttpServletResponse response, String uuid) throws IOException { try { //uuid不能为空 AssertUtils.isBlank(uuid, ErrorCode.IDENTIFIER_NOT_NULL); //生成图片验证码 BufferedImage image = captchaService.create(uuid); response.reset(); response.setHeader("Cache-Control", "no-store, no-cache"); response.setContentType("image/jpeg"); ServletOutputStream out = response.getOutputStream(); ImageIO.write(image, "jpg", out); out.close(); } catch (IOException e) { log.error("获取登陆验证码异常", e); } } /** * @description 基层治理平台登录验证码 * * @param response * @return * @author wxz * @date 2021.10.25 14:19:40 */ @GetMapping("ic-login-captcha") public void icLoginCaptcha(HttpServletResponse response, String uuid) throws IOException { try { //生成图片验证码 BufferedImage image = captchaService.createIcLoginCaptcha(uuid); response.reset(); response.setHeader("Cache-Control", "no-store, no-cache"); response.setContentType("image/jpeg"); ServletOutputStream out = response.getOutputStream(); ImageIO.write(image, "jpg", out); out.close(); } catch (IOException e) { log.error("获取登陆验证码异常", e); } } /** * @param formDTO * @return com.epmet.commons.tools.utils.Result * @Author yinzuomei * @Description 居民端微信小程序登录 * @Date 2020/3/14 14:35 **/ @PostMapping("/resiwxmp/loginbywxcode") public Result loginByWxCode(@RequestBody LoginByWxCodeFormDTO formDTO) { //效验数据 ValidatorUtils.validateEntity(formDTO); return loginService.loginByWxCode(formDTO); } /** * @param formDTO * @return com.epmet.commons.tools.utils.Result * @Author yinzuomei * @Description 手机号+密码登录接口 * @Date 2020/3/14 19:46 **/ @PostMapping("/operweb/loginbypassword") public Result loginByPassword(@RequestBody LoginByPassWordFormDTO formDTO) { //效验数据 ValidatorUtils.validateEntity(formDTO); Result result = loginService.loginByPassword(formDTO); return result; } /** * @param request * @return com.epmet.commons.tools.utils.Result * @Author yinzuomei * @Description 退出登录 * @Date 2020/3/18 22:43 **/ @PostMapping(value = "logout") public Result logout(@LoginUser TokenDto tokenDto, HttpServletRequest request) { return loginService.logoutByToken(tokenDto); } /** * @param formDTO * @return com.epmet.commons.tools.utils.Result * @author yinzuomei * @description 获取用户微信绑定的手机号 * @Date 2020/7/2 14:33 **/ @PostMapping("getresiwxphone") public Result getResiWxPhone(@RequestBody ResiWxPhoneFormDTO formDTO) { String phone = loginService.getResiWxPhone(formDTO); if (StringUtils.isNotBlank(phone) && !"null".equals(phone)) { return new Result().ok(phone); } return new Result().ok(""); } //================start test code========== /** * 校验签名 */ public static boolean checkSignature(String signature, String timestamp, String nonce) { System.out.println("signature:" + signature + "timestamp:" + timestamp + "nonc:" + nonce); String WECHAT_TOKEN = "1jkoyyih83nj8"; String[] arr = new String[]{WECHAT_TOKEN, timestamp, nonce}; // 将token、timestamp、nonce三个参数进行字典序排序 Arrays.sort(arr); StringBuilder content = new StringBuilder(); for (int i = 0; i < arr.length; i++) { content.append(arr[i]); } MessageDigest md = null; String tmpStr = null; try { md = MessageDigest.getInstance("SHA-1"); // 将三个参数字符串拼接成一个字符串进行sha1加密 byte[] digest = md.digest(content.toString().getBytes()); tmpStr = byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } content = null; // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信 System.out.println(tmpStr.equals(signature.toUpperCase())); return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false; } /** * 将字节数组转换为十六进制字符串 * * @param byteArray * @return */ private static String byteToStr(byte[] byteArray) { String strDigest = ""; for (int i = 0; i < byteArray.length; i++) { strDigest += byteToHexStr(byteArray[i]); } return strDigest; } /** * 将字节转换为十六进制字符串 * * @param mByte * @return */ private static String byteToHexStr(byte mByte) { char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; char[] tempArr = new char[2]; tempArr[0] = Digit[(mByte >>> 4) & 0X0F]; tempArr[1] = Digit[mByte & 0X0F]; String s = new String(tempArr); return s; } /** * 打开开发者模式签名认证 * @param signature * @param timestamp * @param nonce * @param echostr * @return */ @ResponseBody @RequestMapping(value = "/service", method = RequestMethod.GET) public Object defaultView(String signature, String timestamp, String nonce, String echostr) { if (echostr == null || echostr.isEmpty()) { return nonce; } if (this.checkSignature(signature, timestamp, nonce)) { return echostr; } return nonce; } }