|
|
@@ -1,10 +1,29 @@
|
|
|
package com.uas.sso.controller;
|
|
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.uas.message.mail.service.MailService;
|
|
|
+import com.uas.sso.SSOHelper;
|
|
|
+import com.uas.sso.SSOToken;
|
|
|
+import com.uas.sso.core.Const;
|
|
|
+import com.uas.sso.core.PasswordStrength;
|
|
|
+import com.uas.sso.core.Status;
|
|
|
+import com.uas.sso.entity.*;
|
|
|
import com.uas.sso.service.UserService;
|
|
|
+import com.uas.sso.util.CaptchaUtil;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.ui.ModelMap;
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
+import org.springframework.web.bind.annotation.PathVariable;
|
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
+import org.springframework.web.bind.annotation.RequestMethod;
|
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
|
|
|
|
+import javax.servlet.ServletException;
|
|
|
+import java.io.IOException;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
/**
|
|
|
* 重置密码controller
|
|
|
*
|
|
|
@@ -18,5 +37,331 @@ public class ResetPasswordController extends BaseController {
|
|
|
@Autowired
|
|
|
private UserService userService;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private MailService mailService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 重置密码验证码存session的key
|
|
|
+ */
|
|
|
+ private static final String RESET_CAPTCHA = "resetCaptcha";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 类型 重置密码
|
|
|
+ */
|
|
|
+ private static final String TYPE_RESET = "reset";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 类型 修改密码
|
|
|
+ */
|
|
|
+ private static final String TYPE_UPDATE = "update";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * token有效期
|
|
|
+ */
|
|
|
+ private static final int EXPIRES = 24*60*60;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 找回密码校验手机号
|
|
|
+ * 根据手机号获取用户信息,之后修改密码直接使用这个信息
|
|
|
+ *
|
|
|
+ * @param mobile
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @RequestMapping(value = "/checkCaptcha", method = RequestMethod.POST)
|
|
|
+ public ModelMap checkCaptcha(String mobile, String mobileArea, String captcha) {
|
|
|
+ // 校验手机号
|
|
|
+ User user = userService.findByMobile(mobile);
|
|
|
+ if (user == null) {
|
|
|
+ return error("用户不存在,请输入正确的手机号");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验验证码
|
|
|
+ String resetCaptcha = (String) request.getSession().getAttribute(RESET_CAPTCHA);
|
|
|
+ if (StringUtils.isEmpty(resetCaptcha)) {
|
|
|
+ return error("未获取验证码");
|
|
|
+ }
|
|
|
+ if (!resetCaptcha.equals(captcha)) {
|
|
|
+ return error("请输入正确的验证码");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置返回值
|
|
|
+ request.getSession().setAttribute("user", user);
|
|
|
+ return success();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取图片验证码
|
|
|
+ */
|
|
|
+ @RequestMapping(value = "/checkCaptcha", method = RequestMethod.GET)
|
|
|
+ public void checkCaptcha() {
|
|
|
+ try {
|
|
|
+ // 获取验证码
|
|
|
+ CaptchaUtil.outputCaptcha(request, response, RESET_CAPTCHA);
|
|
|
+ } catch (ServletException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取可以校验方式
|
|
|
+ *
|
|
|
+ * @param type 修改密码类型
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @RequestMapping(value = "/CheckType/{type}", method = RequestMethod.GET)
|
|
|
+ public ModelMap getCheckType(@PathVariable String type) {
|
|
|
+ // 找到用户信息
|
|
|
+ User user = null;
|
|
|
+ if (TYPE_RESET.equals(type)) {
|
|
|
+ // 调用类型为重置密码,重置密码可以通过session获得用户信息
|
|
|
+ user = (User) request.getSession().getAttribute("user");
|
|
|
+ if (user == null) {
|
|
|
+ return error("请求超时,请刷新重试!");
|
|
|
+ }
|
|
|
+ } else if (TYPE_UPDATE.equals(type)) {
|
|
|
+ // 调用类型为修改密码,修改密码可以通过cookie获得用户信息
|
|
|
+ SSOToken token = SSOHelper.getToken(request);
|
|
|
+ UserAccount userAccount = JSON.parseObject(token.getData(), UserAccount.class);
|
|
|
+ user = userService.findOne(userAccount.getUserUU());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置返回数据
|
|
|
+ ModelMap data = new ModelMap();
|
|
|
+ data.put("mobile", Status.AUTHENTICATED.getCode() == user.getMobileValidCode() ? user.getMobile() : null);
|
|
|
+ data.put("email", Status.AUTHENTICATED.getCode() == user.getEmailValidCode() ? user.getEmail() : null);
|
|
|
+ request.getSession().setAttribute("user", user);
|
|
|
+ return success();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 重置密码第一步设置token
|
|
|
+ * @param userUU 用户uu号
|
|
|
+ * @return tokenId
|
|
|
+ */
|
|
|
+ private String setToken(Long userUU) {
|
|
|
+
|
|
|
+ Token token = new Token(userUU, EXPIRES);
|
|
|
+ return token.getId();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通过密码重置密码
|
|
|
+ * @param password 密码
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @RequestMapping(value = "/check/password", method = RequestMethod.POST)
|
|
|
+ public ModelMap checkByPassword(String password) {
|
|
|
+ // 通过session获取当前找回密码的用户
|
|
|
+ User user = (User) request.getSession().getAttribute("user");
|
|
|
+ if (StringUtils.isEmpty(user)) {
|
|
|
+ return error("请求超时,请刷新重试!");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验密码
|
|
|
+ String encryPwd = userService.getEncryPassword(Const.ENCRY_FORMAT, password, user.getSalt());
|
|
|
+ if (!encryPwd.equals(password)) {
|
|
|
+ return error("密码错误");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置token,并返回
|
|
|
+ String tokenId = setToken(user.getUserUU());
|
|
|
+ return success(new ModelMap("token", tokenId));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通过手机号重置密码,获取验证码
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @RequestMapping(value = "/check/mobile", method = RequestMethod.GET)
|
|
|
+ public ModelMap checkByMobile() {
|
|
|
+ // 从session中获取用户信息
|
|
|
+ User user = (User) request.getSession().getAttribute("user");
|
|
|
+ if (StringUtils.isEmpty(user)) {
|
|
|
+ return error("请求超时,请刷新重试!");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取验证码
|
|
|
+ String token = getMobileCode(user.getMobile());
|
|
|
+
|
|
|
+ // 设置返回数据
|
|
|
+ ModelMap data = new ModelMap();
|
|
|
+ data.put("token", token);
|
|
|
+ request.getSession().setAttribute("token", token);
|
|
|
+ return success(data);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通过手机号重置密码,校验验证码
|
|
|
+ *
|
|
|
+ * @param code 用户输入的验证码
|
|
|
+ * @param token 验证码id
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @RequestMapping(value = "/check/mobile", method = RequestMethod.POST)
|
|
|
+ public ModelMap checkByMobile(String code, String token) {
|
|
|
+ // 从session中获取用户信息
|
|
|
+ User user = (User) request.getSession().getAttribute("user");
|
|
|
+ if (StringUtils.isEmpty(user)) {
|
|
|
+ return error("请求超时,请刷新重试!");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验token是否正确
|
|
|
+ String sessionToken = (String) request.getSession().getAttribute("token");
|
|
|
+ if (StringUtils.isEmpty(sessionToken) || sessionToken.equals(token)) {
|
|
|
+ return error("请重新获取验证码");
|
|
|
+ }
|
|
|
+ if (StringUtils.isEmpty(code)) {
|
|
|
+ return error("请输入验证码");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验验证码并删除token
|
|
|
+ checkMobileCode(token, user.getMobile(), code);
|
|
|
+ tokenService.delete(token);
|
|
|
+
|
|
|
+ // 设置token,并返回
|
|
|
+ String tokenId = setToken(user.getUserUU());
|
|
|
+ return success(new ModelMap("token", tokenId));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通过邮箱重置密码,发送邮箱确认
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @RequestMapping(value = "/check/email", method = RequestMethod.GET)
|
|
|
+ public ModelMap checkByEmail() {
|
|
|
+ // 从session中获取用户信息
|
|
|
+ User user = (User) request.getSession().getAttribute("user");
|
|
|
+ if (StringUtils.isEmpty(user)) {
|
|
|
+ return error("请求超时,请刷新重试!");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置发送邮件信息
|
|
|
+ int expires = 24*60*60;
|
|
|
+ Token token = new Token("user", expires);
|
|
|
+ ModelMap data = new ModelMap();
|
|
|
+ data.put("vipName", user.getVipName());
|
|
|
+ // TODO 邮件认证地址
|
|
|
+ data.put("url", "http://192.168.253.66:8081/sso/resetPwd/check/question?token="+token);
|
|
|
+
|
|
|
+ // 发送邮件
|
|
|
+ String email = user.getEmail();
|
|
|
+ if (!StringUtils.isEmpty(email)) {
|
|
|
+ Setting mailTplId = settingService.findOne("templateForSendMailWhenResetPassword");
|
|
|
+ if (!StringUtils.isEmpty(mailTplId)) {
|
|
|
+ mailService.send(mailTplId.getValue(), email, data);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return success();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 重置密码第二步,认证密保
|
|
|
+ * @param token
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @RequestMapping(value = "/check/question", method = RequestMethod.GET)
|
|
|
+ public ModelMap checkByQuestion(String token) {
|
|
|
+ // 校验token
|
|
|
+ if (StringUtils.isEmpty(token)) {
|
|
|
+ return error("请刷新重试");
|
|
|
+ }
|
|
|
+ Token existToken = tokenService.findOne(token);
|
|
|
+ if (existToken == null) {
|
|
|
+ return error("认证信息已过期,清刷新重试!");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询密保
|
|
|
+ Long userUU = (Long) existToken.getBind();
|
|
|
+ User user = userService.findOne(userUU);
|
|
|
+ if (user == null) {
|
|
|
+ return error("认证信息错误,清刷新重试!");
|
|
|
+ }
|
|
|
+ tokenService.delete(token);
|
|
|
+
|
|
|
+ // 返回用户密保,token
|
|
|
+ existToken = new Token(user, EXPIRES);
|
|
|
+ ModelMap data = new ModelMap();
|
|
|
+ data.put("token",existToken.getId());
|
|
|
+ data.put("question", user.getQuestions());
|
|
|
+ return success(data);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 重置密码第二步,认证密保
|
|
|
+ * @param token
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @RequestMapping(value = "/check/question", method = RequestMethod.POST)
|
|
|
+ public ModelMap checkByQuestion(String token, List<Map<String, Object>> answers) {
|
|
|
+ // 校验token是否正确
|
|
|
+ if (StringUtils.isEmpty(token)) {
|
|
|
+ return error("请刷新重试");
|
|
|
+ }
|
|
|
+ Token expireToken = tokenService.findOne(token);
|
|
|
+ if (expireToken == null) {
|
|
|
+ return error("请求超时,请刷新重试");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验密保答案
|
|
|
+ User user = (User) expireToken.getBind();
|
|
|
+ List<UserQuestion> questions = user.getQuestions();
|
|
|
+ Map<Long, String> userAnswer = new HashMap<>(questions.size());
|
|
|
+ for (UserQuestion question : questions) {
|
|
|
+ userAnswer.put(question.getId(), question.getAnswer());
|
|
|
+ }
|
|
|
+ for (Map<String, Object> answer : answers) {
|
|
|
+ if (!answer.get("answer").equals(userAnswer.get(answer.get("id")))){
|
|
|
+ return error("答案错误");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ tokenService.delete(token);
|
|
|
+
|
|
|
+ // 返回token
|
|
|
+ expireToken = new Token(user, EXPIRES);
|
|
|
+ ModelMap data = new ModelMap();
|
|
|
+ data.put("token", expireToken.getId());
|
|
|
+ return success(data);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 重置密码第三步,重置密码
|
|
|
+ * @param password 新密码
|
|
|
+ * @param token tokenId,包含用户信息
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @RequestMapping(method = RequestMethod.POST)
|
|
|
+ public ModelMap resetPassword(String password, String token) {
|
|
|
+ // 校验token是否正确
|
|
|
+ if (StringUtils.isEmpty(token)) {
|
|
|
+ return error("请刷新重试");
|
|
|
+ }
|
|
|
+ Token expireToken = tokenService.findOne(token);
|
|
|
+ if (expireToken == null) {
|
|
|
+ return error("请求超时,请刷新重试");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验密码
|
|
|
+ PasswordStrength passwordStrength = checkPasswordLevel(password);
|
|
|
+ if (PasswordStrength.WEAK.getValue() == passwordStrength.getValue()) {
|
|
|
+ return error("密码须为8-20字符的英文、数字混合");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 从token中获取用户信息
|
|
|
+ User user = (User) expireToken.getBind();
|
|
|
+
|
|
|
+ // 设置加密后的密码
|
|
|
+ String encryPasswird = userService.getEncryPassword(Const.ENCRY_FORMAT, password, user.getSalt());
|
|
|
+ user.setPassword(encryPasswird);
|
|
|
+ userService.save(user);
|
|
|
|
|
|
+ // 删除token,返回成功
|
|
|
+ tokenService.delete(token);
|
|
|
+ return success();
|
|
|
+ }
|
|
|
}
|