| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- package com.ruoyi.web.service;
- import javax.annotation.Resource;
- import com.google.common.collect.Maps;
- import com.ruoyi.common.core.domain.AjaxResult;
- import com.ruoyi.common.core.domain.entity.SysUser;
- import com.ruoyi.common.enums.AccessFromType;
- import com.ruoyi.common.enums.ErrorCodes;
- import com.ruoyi.common.exception.ErrorException;
- import com.ruoyi.common.utils.PhoneUtils;
- import com.ruoyi.dz.domain.DzCards;
- import com.ruoyi.dz.service.IDzCardsService;
- import com.ruoyi.dz.service.impl.DzCardsServiceImpl;
- import com.ruoyi.framework.web.service.TokenService;
- import com.ruoyi.system.service.ShortMessageService;
- import com.ruoyi.web.controller.dz.DzCardsController;
- import org.apache.commons.collections4.CollectionUtils;
- import org.apache.commons.lang3.tuple.Pair;
- import org.springframework.beans.factory.annotation.Autowired;
- 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 com.ruoyi.common.constant.CacheConstants;
- import com.ruoyi.common.constant.Constants;
- import com.ruoyi.common.constant.UserConstants;
- 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.BlackListException;
- import com.ruoyi.common.exception.user.CaptchaException;
- import com.ruoyi.common.exception.user.CaptchaExpireException;
- import com.ruoyi.common.exception.user.UserNotExistsException;
- import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
- 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.transaction.annotation.Transactional;
- import java.util.Arrays;
- import java.util.List;
- import java.util.Map;
- /**
- * 登录校验方法
- *
- * @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;
- @Autowired
- private ShortMessageService shortMessageService;
- @Autowired
- private IDzCardsService cardsService;
- /**
- * 登录验证
- * @param mobile
- * @param username
- * @param password
- * @param code
- * @param uuid
- * @return
- */
- public AjaxResult login(String mobile, String username, String password, String code, String uuid,String type) {
- if (StringUtils.isNotBlank(mobile)) {
- //手机验证码登录:{code: "9", uuid: "cc94320c3fce4db5898213b727ac1dc0", mobile: "18774924158", password: "1234"}
- if (!shortMessageService.checkCode(mobile, password)) {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(mobile, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
- throw new CaptchaException();
- }
- loginMobilePreCheck(mobile, password);
- username = mobile;
- password = UserConstants.LOGIN_SMS_PASS;
- } else {
- // 验证码校验
- // 卡密登录json:{code: "0", uuid: "a9eee0b6729f42c4862a57acef8a4bdd", username: "20000025", password: "123456"}
- validateCaptcha(username, code, uuid);
- // 登录前置校验
- loginPreCheck(username, password);
- if(AccessFromType.isFrontApp(type)||AccessFromType.isH5(type)||AccessFromType.isWechat(type)){
- //卡密登录时,要将卡的密码转换为用户的密码。手机号的密码与卡的密码分开
- DzCards card = cardsService.selectDzCardsByCardNo(username);
- if (null==card){
- return AjaxResult.error("卡不存在");
- }
- if (!password.trim().equalsIgnoreCase(card.getPassword())){
- return AjaxResult.error("密码错误");
- }
- String dbPwd = userService.selectPasswordByCardId(card.getCardId());
- if (StringUtils.isNotEmpty(dbPwd)){
- password = dbPwd;
- }
- }
- }
- // 用户验证
- 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()));
- if(e.getCause() instanceof ErrorException) {
- ErrorException errorException = (ErrorException) e.getCause();
- Map map = Maps.newHashMap();
- ErrorCodes errorCode = errorException.getErrorCode();
- map.put("code", errorCode.getCode());
- map.put("message", StringUtils.isNotEmpty(errorException.getMessage()) ? errorException.getMessage() : errorCode.getTitle());
- return AjaxResult.success(map);
- }
- 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
- AjaxResult ajax = AjaxResult.success();
- ajax.put(Constants.TOKEN, tokenService.createToken(loginUser));
- return ajax;
- }
- /**
- * 内部自动登陆,不记录日志
- * @param username
- * @param password
- * @return
- */
- public String loginInner(String username, String 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)
- {
- throw new UserPasswordNotMatchException();
- }
- else
- {
- throw new ServiceException(e.getMessage());
- }
- }
- finally
- {
- AuthenticationContextHolder.clearContext();
- }
- LoginUser loginUser = (LoginUser) authentication.getPrincipal();
- 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();
- }
- }
- public void loginMobilePreCheck(String phoneNumber, String code)
- {
- // 用户名或密码为空 错误
- if (StringUtils.isEmpty(phoneNumber) || StringUtils.isEmpty(code))
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(phoneNumber, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
- throw new UserNotExistsException();
- }
- // 密码如果不在指定范围内 错误
- if (code.length() != 4)
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(phoneNumber, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
- throw new UserPasswordNotMatchException();
- }
- // 用户名不在指定范围内 错误
- if (!PhoneUtils.isPhoneNumber(phoneNumber))
- {
- AsyncManager.me().execute(AsyncFactory.recordLogininfor(phoneNumber, 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(phoneNumber, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked")));
- throw new BlackListException();
- }
- }
- /**
- * 记录登录信息
- *
- * @param userId 用户ID
- */
- public void recordLoginInfo(Long userId)
- {
- userService.updateLoginInfo(userId, IpUtils.getIpAddr(), DateUtils.getNowDate());
- }
- }
|