Browse Source

更新 'ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java'

wx
dos 3 months ago
parent
commit
4a98e27ef2

+ 340 - 215
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java

@@ -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);
+    }
+}