package com.uas.sso.controller; import com.alibaba.fastjson.JSON; import com.uas.message.mail.service.MailService; import com.uas.message.sms.service.SmsService; import com.uas.sso.core.Const; import com.uas.sso.core.PasswordStrength; import com.uas.sso.entity.Setting; import com.uas.sso.entity.Token; import com.uas.sso.exception.VisibleError; import com.uas.sso.service.SettingService; import com.uas.sso.service.TokenService; import com.uas.sso.util.StringUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.ui.ModelMap; import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * controller基础类 * * @author yingp */ public class BaseController { protected static final String defultCharset = "UTF-8"; @Autowired protected HttpServletRequest request; @Autowired protected HttpServletResponse response; @Autowired protected TokenService tokenService; @Autowired protected SmsService smsService; @Autowired protected MailService mailService; @Autowired protected SettingService settingService; protected static boolean isSuccess(ModelMap map) { return Boolean.TRUE.equals(map.get("success")); } protected static Object getContent(ModelMap map) { return map.get("content"); } protected static ModelMap success() { return new ModelMap("success", true); } protected static ModelMap success(Object data) { return new ModelMap("success", true).addAttribute("content", data); } protected static ModelMap error(String errMsg) { return new ModelMap("error", true).addAttribute("errMsg", errMsg); } protected static ModelMap error(Object detail) { return new ModelMap("error", true).addAttribute("errDetail", detail); } protected static ModelMap error(String errCode, String errMsg) { return new ModelMap("error", true).addAttribute("errCode", errCode).addAttribute("errMsg", errMsg); } /** * 输出json格式 * * @param obj * @throws IOException */ protected void printJson(Object obj) throws IOException { response.addHeader("Content-Type", "application/json; charset=" + defultCharset); PrintWriter printWriter = response.getWriter(); printWriter.append(JSON.toJSONString(obj)); printWriter.flush(); printWriter.close(); } /** * 响应Ajax请求 * * @param content 响应内容 * @throws IOException */ protected void printJsonP(String callback, Object content) throws IOException { if (!content.getClass().isAssignableFrom(String.class)) { content = JSON.toJSON(content); } response.setContentType("text/html;charset=" + defultCharset); PrintWriter out = response.getWriter(); out.print(callback + "(" + content + ")"); out.flush(); } /** * 输出流 * * @param fileName 文件名 * @param bytes * @throws IOException */ protected ResponseEntity outputStream(String fileName, byte[] bytes) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); headers.setContentDispositionFormData("attachment", fileName); return new ResponseEntity(bytes, headers, HttpStatus.CREATED); } /** * 校验密码强度 * * @param password 密码 * @return PasswordStrength枚举 * @throws VisibleError 用户可见异常 */ protected PasswordStrength checkPasswordLevel(String password) throws VisibleError { String strongRegex = "^(?=.{8,20})(((?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]))|((?=.*[0-9])((?=.*[a-zA-Z]))(?=.*[^a-zA-Z0-9]))).*$"; String mediumRegex = "^(?=.{8,20})(((?=.*[0-9])(?=.*[a-z]))|((?=.*[0-9])(?=.*[A-Z]))).*$"; if (password == null) { throw new VisibleError("密码不能为空"); } if (password.matches(strongRegex)) { return PasswordStrength.STRONG; } else if (password.matches(mediumRegex)) { return PasswordStrength.MEDIUM; } else { return PasswordStrength.WEAK; } } /** * 获取验证码 * * @param mobile 手机号 * @param email 邮箱 * @return tokenId */ protected String getValidCode(String mobile, String email) { // 随机获得验证码 String code = StringUtil.getRandomNumber(6); Token token = new Token(code, 10 * 60); System.out.println(code); // 设置绑定手机,防止获取验证码之后修改手机号 token.setMobile(mobile); token.setEmail(email); // 将token存到Redis服务器上 tokenService.save(token); // 将验证码发送到手机上 ModelMap data = new ModelMap(); data.put("checkcode", code); // 手机短信 try { if (!StringUtils.isEmpty(mobile)) { Setting smsTplId = settingService.findOne("templateForSendSmsWhenRegister"); if (!StringUtils.isEmpty(smsTplId)) { smsService.send(smsTplId.getValue(), mobile, new Object[]{code}); } } } catch (Exception e) { e.printStackTrace(); } // 邮件 try { if (!StringUtils.isEmpty(email)) { Setting mailTplId = settingService.findOne("templateForSendEmailWhenRegister"); if (!StringUtils.isEmpty(mailTplId)) { mailService.send(mailTplId.getValue(), email, data); } } } catch (Exception e) { e.printStackTrace(); } // 返回tokenId return token.getId(); } /** * 获取手机号验证码 * * @param mobile 手机号 * @return tokenId */ protected String getMobileCode(String mobile) { return getValidCode(mobile, null); } /** * 获取邮箱验证码 * * @param email 邮箱 * @return */ protected String getEmailCode(String email) { return getValidCode(null, email); } /** * 校验验证码 * * @param token 验证码tokenID * @param mobile 手机号 * @param email 邮箱 * @param code 验证码 * @return * @throws VisibleError 校验失败则抛异常 * 当参数异常,token过期或者token绑定的手机号不对时抛出此异常 */ protected void checkValidCode(String token, String mobile, String email, String code) { // 校验参数 if (StringUtils.isEmpty(token) || StringUtils.isEmpty(code)) { throw new VisibleError("参数错误"); } Token existToken = tokenService.findOne(token); if (existToken == null || existToken.isExpired()) { throw new VisibleError("验证码已经失效,请重新获取"); } if (!StringUtils.isEmpty(existToken.getMobile()) && !existToken.getMobile().equals(mobile)) { throw new VisibleError("手机号被修改,请重新获取验证码"); } if (!StringUtils.isEmpty(existToken.getEmail()) && !existToken.getEmail().equals(email)) { throw new VisibleError("手机号被修改,请重新获取验证码"); } // 校验验证码 String existCode = existToken.getBind().toString(); if (!code.equals(existCode)) { throw new VisibleError("验证码错误"); } } /** * 校验手机号验证码 * * @param token 验证码tokenID * @param mobile 手机号 * @param code 验证码 */ protected void checkMobileCode(String token, String mobile, String code) { checkValidCode(token, mobile, null, code); } /** * 校验手机号验证码 * * @param token 验证码tokenID * @param email 邮箱 * @param code 验证码 */ protected void checkEmailCode(String token, String email, String code) { checkValidCode(token, null, email, code); } /** * 校验手机号格式 * * @param mobile 手机号 * @param mobileArea 手机号所属区域 */ protected void checkMobile(String mobile, String mobileArea) { // 由于现在不考虑手机号所属区域,默认为中国大陆 mobileArea = mobileArea == null ? Const.CONTINENT : mobileArea; // 校验手机号 if (Const.CONTINENT.equals(mobileArea)) { if (!mobile.matches(Const.REGEXP_MOBILE_CONTINENT)) { throw new VisibleError("请输入正确的手机号格式"); } } else if (Const.HONGKONG.equals(mobileArea)) { if (!mobile.matches(Const.REGEXP_MOBILE_HONGKONG)) { throw new VisibleError("请输入正确的手机号格式"); } } else { throw new VisibleError("未找到所选地区"); } } }