From bf95182e7f9c80f938a97762d1b7f2930d5cc793 Mon Sep 17 00:00:00 2001 From: xd <844539747@qq.com> Date: Sun, 10 Mar 2024 15:15:40 +0800 Subject: [PATCH] =?UTF-8?q?'=E7=A7=BB=E5=8A=A8=E7=AB=AF=E9=80=82=E9=85=8D'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/system/LoginController.java | 78 ++++++ .../web/controller/system/UserController.java | 94 +++++++ .../framework/config/SecurityConfig.java | 3 +- .../web/service/MobileLoginService.java | 237 ++++++++++++++++++ .../com/ruoyi/system/domain/LoginParams.java | 127 ++++++++++ 5 files changed, 538 insertions(+), 1 deletion(-) create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/LoginController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/UserController.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/MobileLoginService.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/domain/LoginParams.java diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/LoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/LoginController.java new file mode 100644 index 0000000..aa8e5d3 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/LoginController.java @@ -0,0 +1,78 @@ +package com.ruoyi.web.controller.system; + + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.framework.web.service.MobileLoginService; +import com.ruoyi.framework.web.service.TokenService; +import com.ruoyi.system.domain.LoginParams; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; + +/** + * 登录控制器 + * + * @author SK + * @since 2018/6/13 + */ +@RestController +@RequestMapping("/mobile/login") +public class LoginController{ + + @Autowired(required = false) + private TokenService tokenService; + + @Autowired(required = false) + private MobileLoginService loginService; + + + + /** + * 会员登录 + * @return -1 用户名或密码错误 -2 账号冻结 -3 账号锁定 1 成功 -4 验证码错误 + */ + @PostMapping("/loginByPassword") + @ResponseBody + public AjaxResult loginByPassword(HttpServletRequest request) { + String username = request.getParameter("username"); + String password = request.getParameter("password"); + String phoneNo = request.getParameter("phoneNo"); + String validCode = request.getParameter("validCode"); + String loginType = request.getParameter("loginType"); + // 登录结果 + LoginParams loginParams = new LoginParams(); + loginParams.setUsername(username); + loginParams.setPassword(password); + loginParams.setPhoneNo(phoneNo); + loginParams.setValidCode(validCode); + loginParams.setLoginType(loginType); + return loginService.login(loginParams); + } + /** + * 发送验证码 + */ + @PostMapping("/sendCode") + @ResponseBody + public AjaxResult sendRegisterCode(HttpServletRequest request) { + String phoneNo = request.getParameter("phoneNo"); + String validCodeType = request.getParameter("validCodeType"); + // 登录结果 + LoginParams loginParams = new LoginParams(); + loginParams.setPhoneNo(phoneNo); + loginParams.setValidCodeType(validCodeType); + return loginService.sendCode(loginParams); + } + + @GetMapping("/logout") + @ResponseBody + public AjaxResult logout(HttpServletRequest request) { + LoginUser loginUser = tokenService.getLoginUser(request); + if(null != loginUser){ + tokenService.delLoginUser(loginUser.getToken(),loginUser.getUser().getUserId()); + } + return AjaxResult.success("退出成功!"); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/UserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/UserController.java new file mode 100644 index 0000000..1f4e7ea --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/UserController.java @@ -0,0 +1,94 @@ +package com.ruoyi.web.controller.system; + + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.web.service.MobileLoginService; +import com.ruoyi.framework.web.service.TokenService; +import com.ruoyi.system.domain.LoginParams; +import com.ruoyi.system.service.ISysUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; + +/** + * 登录控制器 + * + * @author SK + * @since 2018/6/13 + */ +@RestController +@RequestMapping("/mobile/user") +public class UserController { + + @Autowired + private ISysUserService sysUserService; + + + @Autowired + private TokenService tokenService; + + @Autowired + private MobileLoginService loginService; + + /** + * 注册用户 + * + * @return -1 用户名或密码错误 -2 账号冻结 -3 账号锁定 1 成功 -4 验证码错误 + */ + @PostMapping("/registerUser") + @ResponseBody + public AjaxResult registerUser(HttpServletRequest request) { + String phoneNo = request.getParameter("phoneNo"); + String validCode = request.getParameter("validCode"); + // 登录结果 + LoginParams loginParams = new LoginParams(); + loginParams.setPhoneNo(phoneNo); + loginParams.setValidCode(validCode); + return loginService.registerUser(loginParams); + } + + /** + * 获取用户信息 + * + * @return 用户信息 + */ + @GetMapping("getUserInfo") + public AjaxResult getUserInfo(HttpServletRequest request) { + LoginUser loginUser = tokenService.getLoginUser(request); + SysUser user = sysUserService.selectUserById(loginUser.getUser().getUserId()); + AjaxResult ajax = AjaxResult.success(); + ajax.put("user", user); + return ajax; + } + + @PostMapping({"saveUserInfo"}) + @ResponseBody + public AjaxResult saveUserInfo(SysUser user, HttpServletRequest request) { + AjaxResult ajax = AjaxResult.success("个人信息修改成功!"); + SysUser currentUser = SecurityUtils.getLoginUser().getUser(); + currentUser = sysUserService.selectUserById(currentUser.getUserId()); + if (StringUtils.isNotBlank(user.getNickName())) { + currentUser.setNickName(user.getNickName()); + } + if (StringUtils.isNotBlank(user.getEmail())) { + currentUser.setEmail(user.getEmail()); + } else { + currentUser.setEmail(""); + } + if (StringUtils.isNotBlank(user.getPhonenumber())) { + currentUser.setPhonenumber(user.getPhonenumber()); + } else { + currentUser.setPhonenumber(""); + } + if (StringUtils.isNotBlank(user.getSex())) { + currentUser.setSex(user.getSex()); + } + sysUserService.updateUser(currentUser); + return ajax; + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java index 3023e93..e8410d4 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java @@ -126,7 +126,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter // 过滤请求 .authorizeRequests() // 对于登录login 注册register 验证码captchaImage 允许匿名访问 - .antMatchers("/login", "/register", "/captchaImage", "/noPwdLogin").permitAll() + .antMatchers("/login", "/register", "/captchaImage", "/noPwdLogin").anonymous() + .antMatchers("/mobile/login/**").permitAll() // 静态资源,可匿名访问 .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/MobileLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/MobileLoginService.java new file mode 100644 index 0000000..b2002d9 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/MobileLoginService.java @@ -0,0 +1,237 @@ +package com.ruoyi.framework.web.service; + + +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.AjaxResult; +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.UserPasswordNotMatchException; +import com.ruoyi.common.utils.DictUtils; +import com.ruoyi.common.utils.MessageUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.manager.AsyncManager; +import com.ruoyi.framework.manager.factory.AsyncFactory; +import com.ruoyi.framework.security.context.AuthenticationContextHolder; +import com.ruoyi.system.domain.LoginParams; +import com.ruoyi.system.service.ISysPostService; +import com.ruoyi.system.service.ISysRoleService; +import com.ruoyi.system.service.ISysUserService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +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 org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.Objects; +import java.util.Set; + +/** + * 移动端登录服务接口 + */ +@Component +public class MobileLoginService { + + private static final Logger log = LoggerFactory.getLogger(MobileLoginService.class); + + @Autowired(required = false) + private TokenService tokenService; + + @Autowired(required = false) + private SysLoginService sysLoginService; + + @Autowired(required = false) + private ISysRoleService sysRoleService; + + @Autowired(required = false) + private AuthenticationManager authenticationManager; + + @Autowired(required = false) + private ISysUserService sysUserService; + + @Autowired(required = false) + private PermissionService permissionService; + + /** + * 注入redis服务 + */ + @Autowired(required = false) + private RedisCache redisCache; + + /** + * 请求时间戳过期时间5分钟 + */ + private static final int REQUEST_TIME_OUT = 1000 * 60 * 5; + + + /** + * jwt密钥 + */ + @Value("${token.secret}") + private String jwtSecretKey; + + public AjaxResult login(LoginParams loginParams) { + log.debug("login and loginParams:{}", loginParams); + + if (Objects.isNull(loginParams)) { + return AjaxResult.error(-6,"登录参数不能为空"); + } + String loginType = loginParams.getLoginType(); + if(StringUtils.isBlank(loginType)){ + return AjaxResult.error(-6,"登录方式不能为空"); + } + //登录方式0验证码登录,1用户名密码登录,2本机一键登录,3微信单点登录 + if(loginType.equals("0")){ + String phoneNo = loginParams.getPhoneNo(); + if(StringUtils.isBlank(phoneNo)){ + return AjaxResult.error(-6,"登录名不能为空"); + } + String validCode = loginParams.getValidCode(); + //2表示登录验证码,校验验证码合法性 + //sysSmsSendService.checkValidCode(phoneNo,validCode,"2"); + loginParams.setUsername(phoneNo); + loginParams.setPassword("SSO_LOGIN"); + }else if(loginType.equals("1")){ + String password = loginParams.getPassword(); + if(StringUtils.isBlank(password)){ + return AjaxResult.error(-6,"密码不能为空"); + } + } + // 用户验证 + Authentication authentication = null; + try + { + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginParams.getUsername(), loginParams.getPassword()); + AuthenticationContextHolder.setContext(authenticationToken); + // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername + authentication = authenticationManager.authenticate(authenticationToken); + } + catch (Exception e) + { + if (e instanceof BadCredentialsException) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginParams.getUsername(), Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); + throw new UserPasswordNotMatchException(); + } + else + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginParams.getUsername(), Constants.LOGIN_FAIL, e.getMessage())); + throw new ServiceException(e.getMessage()); + } + } + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + //loginUser.setSource("app"); + SysUser user = loginUser.getUser(); + // 生成token + String token = tokenService.createToken(loginUser); + AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginParams.getUsername(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); + sysLoginService.recordLoginInfo(user.getUserId()); + //判断用户是否存在管理员角色 + // 角色集合 +// Set roles = permissionService.getRolePermission(user); +// boolean roleFlag = false; +// if(!CollectionUtils.isEmpty(roles)){ +// for (String roleKey : roles) { +// if(roleKey.equals("agent")){ +// roleFlag = true; +// break; +// } +// } +// } + AjaxResult ajax = AjaxResult.success(""); + ajax.put("token",token); + //token过期时间 + ajax.put("expired",loginUser.getExpireTime()); + ajax.put("user",loginUser.getUser()); + ajax.put("isAgent",String.valueOf(true)); + return ajax; + } + /** + * 发送注册验证码 + * @param loginParams + * @return + */ + public AjaxResult sendCode(LoginParams loginParams) { + if (Objects.isNull(loginParams)) { + return AjaxResult.error(-6,"参数为空"); + } + // 验证验证码 + if (StringUtils.isBlank(loginParams.getPhoneNo())) { + return AjaxResult.error(-6,"发送手机号不能为空"); + } + String validCodeType = "2"; + if (StringUtils.isNotBlank(loginParams.getValidCodeType())) { + validCodeType = loginParams.getValidCodeType(); + } + try{ + //SysSmsSend sysSmsSend = sysSmsSendService.sendMessage(loginParams.getPhoneNo(),validCodeType,true); + //String resultFlag = sysSmsSend.getResultFlag(); + String resultFlag = "n"; + if(resultFlag.equals("f")){ + return AjaxResult.error(-6,"对不起手机号【"+loginParams.getPhoneNo()+"】发送短信失败:失败原因:"); + } + }catch (Exception e){ + throw new ServiceException(e.getMessage()); + } + AjaxResult ajax = AjaxResult.success("验证码发送成功"); + return ajax; + } + + /** + * 手机号验证码注册用户 + * @param loginParams + * @return + */ + @Transactional(readOnly = false) + public AjaxResult registerUser(LoginParams loginParams) { + try{ + if (Objects.isNull(loginParams)) { + return AjaxResult.error(-6,"参数为空"); + } + String phoneNo = loginParams.getPhoneNo(); + if (StringUtils.isBlank(phoneNo)) { + return AjaxResult.error(-6,"发送手机号不能为空"); + } + String validCode = loginParams.getValidCode(); + if (StringUtils.isBlank(validCode)) { + return AjaxResult.error(-6,"验证码不能为空"); + } + loginParams.setUsername(phoneNo); + loginParams.setPassword(phoneNo); + loginParams.setLoginType("1"); + return this.login(loginParams); + }catch (Exception e){ + throw new ServiceException(e.getMessage()); + } + } + + /** + * 设置注册用户角色部门岗位信息 + * @param registerUser + * @return + */ + private void setUserDefaultInfo(SysUser registerUser ){ + String registerRoleCode = DictUtils.getDictValue("sys_config","register_role_code",""); + if (StringUtils.isBlank(registerRoleCode)) { + throw new ServiceException("请前往数据字典【sys_config】中维护注册用户角色编码【register_role_code】"); + } + String registerDeptCode = DictUtils.getDictValue("sys_config","register_dept_code",""); + if (StringUtils.isBlank(registerDeptCode)) { + throw new ServiceException("请前往数据字典【sys_config】中维护注册用户部门编码【register_dept_code】"); + } + String registerPostCode = DictUtils.getDictValue("sys_config","register_post_code",""); + if (StringUtils.isBlank(registerPostCode)) { + throw new ServiceException("请前往数据字典【sys_config】中维护注册用户岗位编码【register_post_code】"); + } + + } + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/LoginParams.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/LoginParams.java new file mode 100644 index 0000000..1a15624 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/LoginParams.java @@ -0,0 +1,127 @@ +package com.ruoyi.system.domain; + + + +/** + * 登入参数实体 + */ +public class LoginParams { + + /** + * 用户名 + */ + private String phoneNo; + + /** + * 密码 + */ + private String username; + + /** + * 密码 + */ + private String password; + + /** + * 用户输入的验证码 + */ + private String validCode; + + /** + * session中的验证码 + */ + private String codeInSession; + /** + * 验证码类型1注册验证码2普通登录验证码 + */ + private String validCodeType; + + /** + * 登录来源 0 pc 1 app 2 mobile + */ + private int source; + /** + * 登录方式0验证码登录,1用户名密码登录,2本机一键登录,3微信单点登录 + */ + private String loginType; + + public void setFromApp() { + this.source = 1; + } + + /** + * 验证验证码 是否正确 (目前都不需要验证码) + * + * @return 正确返回true 否则返回false + */ + public boolean validateCode() { + + // 目前都不需要验证码 + return true; + } + + + public String getPhoneNo() { + return phoneNo; + } + + public void setPhoneNo(String phoneNo) { + this.phoneNo = phoneNo; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getValidCode() { + return validCode; + } + + public void setValidCode(String validCode) { + this.validCode = validCode; + } + + public String getCodeInSession() { + return codeInSession; + } + + public void setCodeInSession(String codeInSession) { + this.codeInSession = codeInSession; + } + + public String getValidCodeType() { + return validCodeType; + } + + public void setValidCodeType(String validCodeType) { + this.validCodeType = validCodeType; + } + + public int getSource() { + return source; + } + + public void setSource(int source) { + this.source = source; + } + + public String getLoginType() { + return loginType; + } + + public void setLoginType(String loginType) { + this.loginType = loginType; + } +}