|
@@ -1,215 +1,340 @@
|
|
|
-package com.ruoyi.framework.web.service;
|
|
|
-
|
|
|
-import com.ruoyi.common.constant.CacheConstants;
|
|
|
-import com.ruoyi.common.constant.Constants;
|
|
|
-import com.ruoyi.common.constant.UserConstants;
|
|
|
-import com.ruoyi.common.core.domain.entity.SysUser;
|
|
|
-import com.ruoyi.common.core.domain.model.LoginUser;
|
|
|
-import com.ruoyi.common.core.redis.RedisCache;
|
|
|
-import com.ruoyi.common.exception.ServiceException;
|
|
|
-import com.ruoyi.common.exception.user.*;
|
|
|
-import com.ruoyi.common.utils.DateUtils;
|
|
|
-import com.ruoyi.common.utils.MessageUtils;
|
|
|
-import com.ruoyi.common.utils.StringUtils;
|
|
|
-import com.ruoyi.common.utils.ip.IpUtils;
|
|
|
-import com.ruoyi.framework.manager.AsyncManager;
|
|
|
-import com.ruoyi.framework.manager.factory.AsyncFactory;
|
|
|
-import com.ruoyi.framework.security.context.AuthenticationContextHolder;
|
|
|
-import com.ruoyi.system.service.ISysConfigService;
|
|
|
-import com.ruoyi.system.service.ISysUserService;
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-import org.springframework.beans.factory.annotation.Qualifier;
|
|
|
-import org.springframework.security.authentication.AuthenticationManager;
|
|
|
-import org.springframework.security.authentication.BadCredentialsException;
|
|
|
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
|
-import org.springframework.security.core.Authentication;
|
|
|
-import org.springframework.stereotype.Component;
|
|
|
-
|
|
|
-/**
|
|
|
- * 登录校验方法
|
|
|
- *
|
|
|
- * @author ruoyi
|
|
|
- */
|
|
|
-@Component
|
|
|
-public class SysLoginService {
|
|
|
- @Autowired
|
|
|
- private TokenService tokenService;
|
|
|
-
|
|
|
-// @Resource
|
|
|
-// private AuthenticationManager authenticationManager;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private RedisCache redisCache;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private ISysUserService userService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private ISysConfigService configService;
|
|
|
-
|
|
|
- private final AuthenticationManager authenticationManager;
|
|
|
- private final AuthenticationManager authenticationPhoneManager;
|
|
|
-
|
|
|
- public SysLoginService(@Qualifier("authenticationManager") AuthenticationManager authenticationManager,
|
|
|
- @Qualifier("authenticationPhoneManager") AuthenticationManager authenticationPhoneManager) {
|
|
|
- this.authenticationManager = authenticationManager;
|
|
|
- this.authenticationPhoneManager = authenticationPhoneManager;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 登录验证
|
|
|
- *
|
|
|
- * @param username 用户名
|
|
|
- * @param password 密码
|
|
|
- * @param code 验证码
|
|
|
- * @param uuid 唯一标识
|
|
|
- * @return 结果
|
|
|
- */
|
|
|
- public String login(String username, String password, String code, String uuid, boolean isCommunity) {
|
|
|
- // 验证码校验
|
|
|
- validateCaptcha(username, code, uuid);
|
|
|
- // 登录前置校验
|
|
|
- loginPreCheck(username, password);
|
|
|
- // 用户验证
|
|
|
- Authentication authentication = null;
|
|
|
- try {
|
|
|
- UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
|
|
|
- AuthenticationContextHolder.setContext(authenticationToken);
|
|
|
- // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
|
|
|
- authentication = authenticationManager.authenticate(authenticationToken);
|
|
|
- } catch (Exception e) {
|
|
|
- if (e instanceof BadCredentialsException) {
|
|
|
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
|
|
|
- throw new UserPasswordNotMatchException();
|
|
|
- } else {
|
|
|
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
|
|
|
- throw new ServiceException(e.getMessage());
|
|
|
- }
|
|
|
- } finally {
|
|
|
- AuthenticationContextHolder.clearContext();
|
|
|
- }
|
|
|
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
|
|
|
- LoginUser loginUser = (LoginUser) authentication.getPrincipal();
|
|
|
- recordLoginInfo(loginUser.getUserId());
|
|
|
- // 生成token
|
|
|
- return tokenService.createToken(loginUser);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 校验验证码
|
|
|
- *
|
|
|
- * @param username 用户名
|
|
|
- * @param code 验证码
|
|
|
- * @param uuid 唯一标识
|
|
|
- * @return 结果
|
|
|
- */
|
|
|
- public void validateCaptcha(String username, String code, String uuid) {
|
|
|
- boolean captchaEnabled = configService.selectCaptchaEnabled();
|
|
|
- if (captchaEnabled) {
|
|
|
- String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
|
|
|
- String captcha = redisCache.getCacheObject(verifyKey);
|
|
|
- if (captcha == null) {
|
|
|
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
|
|
|
- throw new CaptchaExpireException();
|
|
|
- }
|
|
|
- redisCache.deleteObject(verifyKey);
|
|
|
- if (!code.equalsIgnoreCase(captcha)) {
|
|
|
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
|
|
|
- throw new CaptchaException();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 登录前置校验
|
|
|
- *
|
|
|
- * @param username 用户名
|
|
|
- * @param password 用户密码
|
|
|
- */
|
|
|
- public void loginPreCheck(String username, String password) {
|
|
|
- // 用户名或密码为空 错误
|
|
|
- if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
|
|
|
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
|
|
|
- throw new UserNotExistsException();
|
|
|
- }
|
|
|
- // 密码如果不在指定范围内 错误
|
|
|
- if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|
|
|
- || password.length() > UserConstants.PASSWORD_MAX_LENGTH) {
|
|
|
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
|
|
|
- throw new UserPasswordNotMatchException();
|
|
|
- }
|
|
|
- // 用户名不在指定范围内 错误
|
|
|
- if (username.length() < UserConstants.USERNAME_MIN_LENGTH
|
|
|
- || username.length() > UserConstants.USERNAME_MAX_LENGTH) {
|
|
|
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
|
|
|
- throw new UserPasswordNotMatchException();
|
|
|
- }
|
|
|
- // IP黑名单校验
|
|
|
- String blackStr = configService.selectConfigByKey("sys.login.blackIPList");
|
|
|
- if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) {
|
|
|
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked")));
|
|
|
- throw new BlackListException();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 记录登录信息
|
|
|
- *
|
|
|
- * @param userId 用户ID
|
|
|
- */
|
|
|
- public void recordLoginInfo(Long userId) {
|
|
|
- SysUser sysUser = new SysUser();
|
|
|
- sysUser.setUserId(userId);
|
|
|
- sysUser.setLoginIp(IpUtils.getIpAddr());
|
|
|
- sysUser.setLoginDate(DateUtils.getNowDate());
|
|
|
- userService.updateUserProfile(sysUser);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 手机号验证码登录
|
|
|
- *
|
|
|
- * @param phone 手机号
|
|
|
- * @param code 验证码
|
|
|
- * @param uuid 唯一标识
|
|
|
- * @return
|
|
|
- */
|
|
|
- public String loginByTelephone(String phone, String code, String uuid) {
|
|
|
-
|
|
|
- if (StringUtils.isEmpty(code)) {
|
|
|
- throw new CaptchaNullException(); //抛出验证码不能为空的异常
|
|
|
- }
|
|
|
- //校验验证码
|
|
|
- //获取缓存内的验证码
|
|
|
- String verifyKey = CacheConstants.SMS_LOGIN_CODE_KEY + phone;
|
|
|
- String smsCode = redisCache.getCacheObject(verifyKey).toString();
|
|
|
- if (StringUtils.isEmpty(smsCode)) {
|
|
|
- throw new CaptchaExpireException(); //抛出验证码失效的异常
|
|
|
- }
|
|
|
-
|
|
|
- if (!smsCode.equalsIgnoreCase(code)) {
|
|
|
- throw new CaptchaException(); //抛出验证码错误的异常
|
|
|
- }
|
|
|
-
|
|
|
- Authentication authentication = null; // 用户验证
|
|
|
- try {
|
|
|
- UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(phone, Constants.CUSTOM_LOGIN_SMS);
|
|
|
- AuthenticationContextHolder.setContext(authenticationToken);
|
|
|
- // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
|
|
|
- authentication = authenticationPhoneManager.authenticate(authenticationToken);
|
|
|
- } catch (Exception e) {
|
|
|
- if (e instanceof BadCredentialsException) {
|
|
|
- throw new UserPasswordNotMatchException(); //抛出账号或者密码错误的异常
|
|
|
- } else {
|
|
|
- throw new ServiceException(e.getMessage()); //抛出其他异常
|
|
|
- }
|
|
|
- } finally {
|
|
|
- AuthenticationContextHolder.clearContext();
|
|
|
- }
|
|
|
- LoginUser loginUser = (LoginUser) authentication.getPrincipal();
|
|
|
- recordLoginInfo(loginUser.getUserId()); //修改sys_user最近登录IP和登录时间
|
|
|
- //成功 删除内存的验证码
|
|
|
- redisCache.deleteObject(verifyKey);
|
|
|
- // 生成token
|
|
|
- return tokenService.createToken(loginUser);
|
|
|
- }
|
|
|
-}
|
|
|
+package com.ruoyi.framework.web.service;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.ruoyi.common.constant.CacheConstants;
|
|
|
+import com.ruoyi.common.constant.Constants;
|
|
|
+import com.ruoyi.common.constant.UserConstants;
|
|
|
+import com.ruoyi.common.core.domain.entity.SysUser;
|
|
|
+import com.ruoyi.common.core.domain.model.LoginUser;
|
|
|
+import com.ruoyi.common.core.redis.RedisCache;
|
|
|
+import com.ruoyi.common.exception.ServiceException;
|
|
|
+import com.ruoyi.common.exception.user.*;
|
|
|
+import com.ruoyi.common.utils.DateUtils;
|
|
|
+import com.ruoyi.common.utils.MessageUtils;
|
|
|
+import com.ruoyi.common.utils.SecurityUtils;
|
|
|
+import com.ruoyi.common.utils.StringUtils;
|
|
|
+import com.ruoyi.common.utils.ip.IpUtils;
|
|
|
+import com.ruoyi.framework.manager.AsyncManager;
|
|
|
+import com.ruoyi.framework.manager.factory.AsyncFactory;
|
|
|
+import com.ruoyi.framework.security.context.AuthenticationContextHolder;
|
|
|
+import com.ruoyi.system.mapper.SysUserMapper;
|
|
|
+import com.ruoyi.system.service.ISysConfigService;
|
|
|
+import com.ruoyi.system.service.ISysUserService;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Qualifier;
|
|
|
+import org.springframework.security.authentication.AuthenticationManager;
|
|
|
+import org.springframework.security.authentication.BadCredentialsException;
|
|
|
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
|
+import org.springframework.security.core.Authentication;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import java.util.Random;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 登录校验方法
|
|
|
+ *
|
|
|
+ * @author ruoyi
|
|
|
+ */
|
|
|
+@Component
|
|
|
+public class SysLoginService {
|
|
|
+ @Autowired
|
|
|
+ private SysUserMapper userMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private TokenService tokenService;
|
|
|
+
|
|
|
+// @Resource
|
|
|
+// private AuthenticationManager authenticationManager;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private RedisCache redisCache;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ISysUserService userService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ISysConfigService configService;
|
|
|
+
|
|
|
+ private final AuthenticationManager authenticationManager;
|
|
|
+ private final AuthenticationManager authenticationPhoneManager;
|
|
|
+
|
|
|
+ public SysLoginService(@Qualifier("authenticationManager") AuthenticationManager authenticationManager,
|
|
|
+ @Qualifier("authenticationPhoneManager") AuthenticationManager authenticationPhoneManager) {
|
|
|
+ this.authenticationManager = authenticationManager;
|
|
|
+ this.authenticationPhoneManager = authenticationPhoneManager;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 登录验证
|
|
|
+ *
|
|
|
+ * @param username 用户名
|
|
|
+ * @param password 密码
|
|
|
+ * @param code 验证码
|
|
|
+ * @param uuid 唯一标识
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public String login(String username, String password, String code, String uuid, boolean isCommunity) {
|
|
|
+ // 验证码校验
|
|
|
+ validateCaptcha(username, code, uuid);
|
|
|
+ // 登录前置校验
|
|
|
+ loginPreCheck(username, password);
|
|
|
+ // 用户验证
|
|
|
+ Authentication authentication = null;
|
|
|
+ try {
|
|
|
+ UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
|
|
|
+ AuthenticationContextHolder.setContext(authenticationToken);
|
|
|
+ // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
|
|
|
+ authentication = authenticationManager.authenticate(authenticationToken);
|
|
|
+ } catch (Exception e) {
|
|
|
+ if (e instanceof BadCredentialsException) {
|
|
|
+ AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
|
|
|
+ throw new UserPasswordNotMatchException();
|
|
|
+ } else {
|
|
|
+ AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
|
|
|
+ throw new ServiceException(e.getMessage());
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ AuthenticationContextHolder.clearContext();
|
|
|
+ }
|
|
|
+ AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
|
|
|
+ LoginUser loginUser = (LoginUser) authentication.getPrincipal();
|
|
|
+ recordLoginInfo(loginUser.getUserId());
|
|
|
+ // 生成token
|
|
|
+ return tokenService.createToken(loginUser);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 微信登录
|
|
|
+ *
|
|
|
+ * @param Result 登录凭证 只能用一次
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public String wxLogin(String[] Result){
|
|
|
+ //字符串转json
|
|
|
+ //JSONObject jsonObject = JSONObject.parseObject(Result);
|
|
|
+
|
|
|
+ //String unionid = jsonObject.getString("unionid");
|
|
|
+ String openId = Result[0];//jsonObject.getString("openid");
|
|
|
+ System.out.println("openId:"+openId);
|
|
|
+
|
|
|
+ // 获取 province
|
|
|
+ //String province= jsonObject.getString("province");
|
|
|
+ // 获取 nickName
|
|
|
+ String nickName = Result[1];//jsonObject.getString("nickname");
|
|
|
+ System.out.println("nickName:"+nickName);
|
|
|
+ // 获取 avatarUrl
|
|
|
+ String avatarUrl = Result[2];//jsonObject.getString("headimgurl");
|
|
|
+ System.out.println("avatarUrl:"+avatarUrl);
|
|
|
+
|
|
|
+ //生成随机nickName
|
|
|
+ //String nickName = getStringRandom(16);// 生成16位随机昵称
|
|
|
+ //获取头像
|
|
|
+ //String avatarUrl = jsonObject.getString("avatarUrl");
|
|
|
+ //String avatarUrl = "";
|
|
|
+ //还可以获取其他信息
|
|
|
+ //根据openid判断数据库中是否有该用户
|
|
|
+ //根据openid查询用户信息
|
|
|
+
|
|
|
+
|
|
|
+ SysUser wxUser = userMapper.selectWxUserByOpenId(openId);
|
|
|
+
|
|
|
+ //如果查不到,则新增,查到了,则更新
|
|
|
+ SysUser user = new SysUser();
|
|
|
+ if (wxUser == null) {
|
|
|
+ // 新增
|
|
|
+ user.setUserName(getStringRandom(16));// 生成16位随机用户名
|
|
|
+ user.setPassword(SecurityUtils.encryptPassword("rQoMxYUIm0#xX9xv"));
|
|
|
+ user.setNickName(nickName);
|
|
|
+ user.setAvatar(avatarUrl);
|
|
|
+ //wxUser.setUnionId(unionid);
|
|
|
+ user.setOpenId(openId);
|
|
|
+ user.setCreateTime(DateUtils.getNowDate());
|
|
|
+ //新增 用户
|
|
|
+ userMapper.insertUser(user);
|
|
|
+ }else {
|
|
|
+ //更新
|
|
|
+ user = wxUser;
|
|
|
+ user.setPassword(SecurityUtils.encryptPassword("rQoMxYUIm0#xX9xv"));
|
|
|
+ //是否每次微信登录都同步微信头像和昵称
|
|
|
+ //user.setAvatar(avatarUrl);
|
|
|
+ //user.setNickName(nickName);
|
|
|
+ user.setUpdateTime(DateUtils.getNowDate());
|
|
|
+ userMapper.updateUser(user);
|
|
|
+ }
|
|
|
+
|
|
|
+ //组装token信息
|
|
|
+ LoginUser loginUser = new LoginUser();
|
|
|
+ loginUser.setOpenId(openId);
|
|
|
+ //如果有的话设置
|
|
|
+ loginUser.setUser(user);
|
|
|
+ loginUser.setUserId(user.getUserId());
|
|
|
+
|
|
|
+
|
|
|
+ // 登录前置校验
|
|
|
+ loginPreCheck(user.getUserName(), "rQoMxYUIm0#xX9xv");
|
|
|
+ // 用户验证
|
|
|
+ Authentication authentication = null;
|
|
|
+ try {
|
|
|
+ UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUserName(), "rQoMxYUIm0#xX9xv");
|
|
|
+ AuthenticationContextHolder.setContext(authenticationToken);
|
|
|
+ // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
|
|
|
+ authentication = authenticationManager.authenticate(authenticationToken);
|
|
|
+ } catch (Exception e) {
|
|
|
+ if (e instanceof BadCredentialsException) {
|
|
|
+ AsyncManager.me().execute(AsyncFactory.recordLogininfor(user.getUserName(), Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
|
|
|
+ throw new UserPasswordNotMatchException();
|
|
|
+ } else {
|
|
|
+ AsyncManager.me().execute(AsyncFactory.recordLogininfor(user.getUserName(), Constants.LOGIN_FAIL, e.getMessage()));
|
|
|
+ throw new ServiceException(e.getMessage());
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ AuthenticationContextHolder.clearContext();
|
|
|
+ }
|
|
|
+ AsyncManager.me().execute(AsyncFactory.recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
|
|
|
+ loginUser = (LoginUser) authentication.getPrincipal();
|
|
|
+ recordLoginInfo(loginUser.getUserId());
|
|
|
+ // 生成token
|
|
|
+ return tokenService.createToken(loginUser);
|
|
|
+ }
|
|
|
+
|
|
|
+ //生成随机用户名,数字和字母组成,
|
|
|
+ public static String getStringRandom(int length) {
|
|
|
+
|
|
|
+ String val = "";
|
|
|
+ Random random = new Random();
|
|
|
+
|
|
|
+ //参数length,表示生成几位随机数
|
|
|
+ for (int i = 0; i < length; i++) {
|
|
|
+
|
|
|
+ String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
|
|
|
+ //输出字母还是数字
|
|
|
+ if ("char".equalsIgnoreCase(charOrNum)) {
|
|
|
+ //输出是大写字母还是小写字母
|
|
|
+ int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
|
|
|
+ val += (char) (random.nextInt(26) + temp);
|
|
|
+ } else if ("num".equalsIgnoreCase(charOrNum)) {
|
|
|
+ val += String.valueOf(random.nextInt(10));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return val;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 校验验证码
|
|
|
+ *
|
|
|
+ * @param username 用户名
|
|
|
+ * @param code 验证码
|
|
|
+ * @param uuid 唯一标识
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public void validateCaptcha(String username, String code, String uuid) {
|
|
|
+ boolean captchaEnabled = configService.selectCaptchaEnabled();
|
|
|
+ if (captchaEnabled) {
|
|
|
+ String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
|
|
|
+ String captcha = redisCache.getCacheObject(verifyKey);
|
|
|
+ if (captcha == null) {
|
|
|
+ AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
|
|
|
+ throw new CaptchaExpireException();
|
|
|
+ }
|
|
|
+ redisCache.deleteObject(verifyKey);
|
|
|
+ if (!code.equalsIgnoreCase(captcha)) {
|
|
|
+ AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
|
|
|
+ throw new CaptchaException();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 登录前置校验
|
|
|
+ *
|
|
|
+ * @param username 用户名
|
|
|
+ * @param password 用户密码
|
|
|
+ */
|
|
|
+ public void loginPreCheck(String username, String password) {
|
|
|
+ // 用户名或密码为空 错误
|
|
|
+ if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
|
|
|
+ AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
|
|
|
+ throw new UserNotExistsException();
|
|
|
+ }
|
|
|
+ // 密码如果不在指定范围内 错误
|
|
|
+ if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|
|
|
+ || password.length() > UserConstants.PASSWORD_MAX_LENGTH) {
|
|
|
+ AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
|
|
|
+ throw new UserPasswordNotMatchException();
|
|
|
+ }
|
|
|
+ // 用户名不在指定范围内 错误
|
|
|
+ if (username.length() < UserConstants.USERNAME_MIN_LENGTH
|
|
|
+ || username.length() > UserConstants.USERNAME_MAX_LENGTH) {
|
|
|
+ AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
|
|
|
+ throw new UserPasswordNotMatchException();
|
|
|
+ }
|
|
|
+ // IP黑名单校验
|
|
|
+ String blackStr = configService.selectConfigByKey("sys.login.blackIPList");
|
|
|
+ if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) {
|
|
|
+ AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked")));
|
|
|
+ throw new BlackListException();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 记录登录信息
|
|
|
+ *
|
|
|
+ * @param userId 用户ID
|
|
|
+ */
|
|
|
+ public void recordLoginInfo(Long userId) {
|
|
|
+ SysUser sysUser = new SysUser();
|
|
|
+ sysUser.setUserId(userId);
|
|
|
+ sysUser.setLoginIp(IpUtils.getIpAddr());
|
|
|
+ sysUser.setLoginDate(DateUtils.getNowDate());
|
|
|
+ userService.updateUserProfile(sysUser);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 手机号验证码登录
|
|
|
+ *
|
|
|
+ * @param phone 手机号
|
|
|
+ * @param code 验证码
|
|
|
+ * @param uuid 唯一标识
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public String loginByTelephone(String phone, String code, String uuid) {
|
|
|
+
|
|
|
+ if (StringUtils.isEmpty(code)) {
|
|
|
+ throw new CaptchaNullException(); //抛出验证码不能为空的异常
|
|
|
+ }
|
|
|
+ //校验验证码
|
|
|
+ //获取缓存内的验证码
|
|
|
+ String verifyKey = CacheConstants.SMS_LOGIN_CODE_KEY + phone;
|
|
|
+ String smsCode = redisCache.getCacheObject(verifyKey).toString();
|
|
|
+ if (StringUtils.isEmpty(smsCode)) {
|
|
|
+ throw new CaptchaExpireException(); //抛出验证码失效的异常
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!smsCode.equalsIgnoreCase(code)) {
|
|
|
+ throw new CaptchaException(); //抛出验证码错误的异常
|
|
|
+ }
|
|
|
+
|
|
|
+ Authentication authentication = null; // 用户验证
|
|
|
+ try {
|
|
|
+ UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(phone, Constants.CUSTOM_LOGIN_SMS);
|
|
|
+ AuthenticationContextHolder.setContext(authenticationToken);
|
|
|
+ // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
|
|
|
+ authentication = authenticationPhoneManager.authenticate(authenticationToken);
|
|
|
+ } catch (Exception e) {
|
|
|
+ if (e instanceof BadCredentialsException) {
|
|
|
+ throw new UserPasswordNotMatchException(); //抛出账号或者密码错误的异常
|
|
|
+ } else {
|
|
|
+ throw new ServiceException(e.getMessage()); //抛出其他异常
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ AuthenticationContextHolder.clearContext();
|
|
|
+ }
|
|
|
+ LoginUser loginUser = (LoginUser) authentication.getPrincipal();
|
|
|
+ recordLoginInfo(loginUser.getUserId()); //修改sys_user最近登录IP和登录时间
|
|
|
+ //成功 删除内存的验证码
|
|
|
+ redisCache.deleteObject(verifyKey);
|
|
|
+ // 生成token
|
|
|
+ return tokenService.createToken(loginUser);
|
|
|
+ }
|
|
|
+}
|