1、登陆接口完成

2、全局开启登录验证
3、登录后,获取用户信息接口,获取菜单接口完成
This commit is contained in:
高雄 2025-05-27 14:17:12 +08:00
parent 98950780f5
commit 08d48aac2b
11 changed files with 231 additions and 138 deletions

View File

@ -41,18 +41,18 @@ public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册 Sa-Token 拦截器定义详细认证规则
// registry.addInterceptor(new SaInterceptor(handler -> {
// SaRouter
// .match("/**") // 拦截的 path 列表可以写多个 */
// .notMatch(excludePaths())
// .check(r -> StpUtil.checkLogin());
// })).addPathPatterns("/**");
registry.addInterceptor(new SaInterceptor(handler -> {
SaRouter
.match("/**") // 拦截的 path 列表可以写多个 */
.notMatch(excludePaths())
.check(r -> StpUtil.checkLogin());
})).addPathPatterns("/**");
}
// 动态获取哪些 path 可以忽略鉴权
public List<String> excludePaths() {
// 此处仅为示例实际项目你可以写任意代码来查询这些path
return Arrays.asList("/login", "/favicon.ico", "/favicon.ico", "/doc.html", "/swagger-ui/**", "/swagger-resources","/webjars/**", "/v3/api-docs/**", "/**/v3/api-docs", "/static/image/**","/static/image/temp/**");
return Arrays.asList("/auth/login", "/favicon.ico", "/favicon.ico", "/doc.html", "/swagger-ui/**", "/swagger-resources","/webjars/**", "/v3/api-docs/**", "/**/v3/api-docs", "/static/image/**","/static/image/temp/**");
}
}

View File

@ -15,33 +15,48 @@ public class Constants {
*/
public static final String SERVICE_EXCEPTION = "000002";
/**
* 参数异常
*/
public static final String PARAMETER_EXCEPTION = "000003";
public static final String SERVICE_EXCEPTION_MESSAGE = "服务开小差,请稍后再试!";
/**
* 账号密码错误
*/
public static final String PASSWORD_ERROR_EXCEPTION = "500000";
public static final String ACCOUNT_ERROR_EXCEPTION = "500000";
public static final String ACCOUNT_ERROR_EXCEPTION_MESSAGE = "用户名或者密码错误!";
/**
* 账号密码错误
*/
public static final String PASSWORD_ERROR_EXCEPTION = "500001";
public static final String PASSWORD_ERROR_EXCEPTION_MESSAGE = "用户名或者密码错误!";
/**
* 账号密码错误
*/
public static final String PASSWORD_EXCEPTION = "500002";
public static final String PASSWORD_EXCEPTION_MESSAGE = "用户名或者密码错误!";
/**
* 账号停用
*/
public static final String USER_DISABLE_EXCEPTION = "500001";
public static final String USER_DISABLE_EXCEPTION = "500100";
public static final String USER_DISABLE_EXCEPTION_MESSAGE = "用户已停用!";
/**
* 默认密码
*/
public static final String DEFAULT_PASSWORD_EXCEPTION = "500002";
public static final String DEFAULT_PASSWORD_EXCEPTION = "500200";
public static final String DEFAULT_PASSWORD_EXCEPTION_MESSAGE = "初始密码,请修改密码后登陆!";
/**
* 参数异常
*/
public static final String PARAMETER_EXCEPTION = "000003";
/**
* 0:代表存在
*/
@ -62,4 +77,14 @@ public class Constants {
*/
public static final Integer STATUS_1 = 1;
/**
* 0:代表显示
*/
public static final String VISIBLE_0 = "0";
/**
* 1:代表隐藏
*/
public static final String VISIBLE_1 = "1";
}

View File

@ -13,10 +13,12 @@ import java.util.List;
* @date 2025/5/23/周五 14:31
* @description
*/
public interface LoginService {
public interface AuthService {
Result<SaTokenInfo> doLogin(LoginReq req);
void doLogout();
List<Tree<String>> getMenuInfo(String userId);
UserInfo getUserInfo(String userId);

View File

@ -0,0 +1,119 @@
package com.dite.znpt.service.impl;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dite.znpt.constant.Constants;
import com.dite.znpt.converts.Converts;
import com.dite.znpt.domain.Result;
import com.dite.znpt.domain.entity.DeptEntity;
import com.dite.znpt.domain.entity.MenuEntity;
import com.dite.znpt.domain.entity.RoleMenuEntity;
import com.dite.znpt.domain.entity.UserEntity;
import com.dite.znpt.domain.vo.LoginReq;
import com.dite.znpt.domain.vo.RoleResp;
import com.dite.znpt.domain.vo.UserInfo;
import com.dite.znpt.service.*;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* @author Bear.G
* @date 2025/5/23/周五 14:31
* @description
*/
@AllArgsConstructor
@Service
public class AuthServiceImpl implements AuthService {
private final UserService userService;
private final UserRoleService userRoleService;
private final UserPostService userPostService;
private final MenuService menuService;
private final RoleMenuService roleMenuService;
private final DeptService deptService;
@Override
public Result<SaTokenInfo> doLogin(LoginReq req) {
String key = SecureUtil.md5(req.getAccount()).substring(8,24);
UserEntity user = userService.getOne(Wrappers.lambdaQuery(UserEntity.class).eq(UserEntity::getAccount, req.getAccount()).eq(UserEntity::getDelFlag, Constants.DEL_FLAG_0));
if(null == user){
return Result.error(Constants.ACCOUNT_ERROR_EXCEPTION, Constants.ACCOUNT_ERROR_EXCEPTION_MESSAGE);
}
try {
String password = SecureUtil.aes(key.getBytes()).decryptStr(req.getPassword());
String pwdCiphertext = SecureUtil.md5(req.getAccount().concat(password).concat(user.getSalt()));
if(!pwdCiphertext.equals(user.getPassword())){
return Result.error(Constants.PASSWORD_ERROR_EXCEPTION, Constants.PASSWORD_ERROR_EXCEPTION_MESSAGE);
}
}catch (Exception e){
return Result.error(Constants.PASSWORD_EXCEPTION, Constants.PASSWORD_EXCEPTION_MESSAGE);
}
if(!user.getStatus().equals(Constants.STATUS_0)){
return Result.error(Constants.USER_DISABLE_EXCEPTION, Constants.USER_DISABLE_EXCEPTION_MESSAGE);
}
if(user.getIsDefaultPassword()){
return Result.error(Constants.DEFAULT_PASSWORD_EXCEPTION, Constants.DEFAULT_PASSWORD_EXCEPTION_MESSAGE);
}
StpUtil.login(user.getUserId());
saveSession(user.getUserId());
return Result.ok(StpUtil.getTokenInfo());
}
@Override
public void doLogout() {
StpUtil.logout();
}
@Override
public List<Tree<String>> getMenuInfo(String userId) {
return (List<Tree<String>>) StpUtil.getSession().get("menuInfo");
}
@Override
public UserInfo getUserInfo(String userId) {
return (UserInfo)StpUtil.getSession().get("userInfo");
}
private void saveSession(String userId){
StpUtil.getSession().set("userInfo", queryUserInfo(userId));
StpUtil.getSession().set("menuInfo", queryMenuInfo(userId));
}
private UserInfo queryUserInfo(String userId){
UserInfo userInfo = new UserInfo();
UserEntity user = userService.getOne(Wrappers.lambdaQuery(UserEntity.class).eq(UserEntity::getUserId, userId).eq(UserEntity::getDelFlag, Constants.DEL_FLAG_0));
userInfo.setUser(Converts.INSTANCE.toUserListResp(user));
if(StrUtil.isNotBlank(user.getDeptId())){
DeptEntity dept = deptService.getOne(Wrappers.lambdaQuery(DeptEntity.class).eq(DeptEntity::getDeptId, user.getDeptId()).eq(DeptEntity::getDelFlag, Constants.DEL_FLAG_0));
userInfo.setDept(Converts.INSTANCE.toDeptResp(dept));
}
userInfo.setRoles(userRoleService.getRolesByUserId(userId));
userInfo.setPosts(userPostService.getPostsByUserId(userId));
return userInfo;
}
private List<Tree<String>> queryMenuInfo(String userId){
List<String> roleIds = userRoleService.getRolesByUserId(userId).stream().map(RoleResp::getRoleId).toList();
if(CollUtil.isEmpty(roleIds)){
return new ArrayList<>();
}
List<String> menuIds = roleMenuService.list(Wrappers.lambdaQuery(RoleMenuEntity.class).in(CollUtil.isNotEmpty(roleIds), RoleMenuEntity::getRoleId, roleIds)).stream().map(RoleMenuEntity::getMenuId).toList();
List<MenuEntity> menuList = menuService.list(
Wrappers.lambdaQuery(MenuEntity.class).in(CollUtil.isNotEmpty(menuIds), MenuEntity::getMenuId,menuIds)
).stream().filter(menu -> Constants.VISIBLE_0.equals(menu.getVisible())).toList();
return MenuServiceImpl.buildMenuTree(menuList);
}
}

View File

@ -36,6 +36,10 @@ public class DeptServiceImpl extends ServiceImpl<DeptMapper, DeptEntity> impleme
@Override
public List<Tree<String>> tree(String deptName) {
List<DeptEntity> deptList = StrUtil.isBlank(deptName) ? this.baseMapper.downwardRecursionSelect(null) : this.baseMapper.upwardRecursionSelect(deptName);
return buildDeptTree(deptList);
}
public static List<Tree<String>> buildDeptTree(List<DeptEntity> deptList) {
//配置
TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
treeNodeConfig.setIdKey("deptId");

View File

@ -1,82 +0,0 @@
package com.dite.znpt.service.impl;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dite.znpt.constant.Constants;
import com.dite.znpt.converts.Converts;
import com.dite.znpt.domain.Result;
import com.dite.znpt.domain.entity.DeptEntity;
import com.dite.znpt.domain.entity.UserEntity;
import com.dite.znpt.domain.vo.LoginReq;
import com.dite.znpt.domain.vo.UserInfo;
import com.dite.znpt.service.*;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* @author Bear.G
* @date 2025/5/23/周五 14:31
* @description
*/
@Service
public class LoginServiceImpl implements LoginService {
@Resource
private UserService userService;
@Resource
private UserRoleService userRoleService;
@Resource
private UserPostService userPostService;
@Resource
private DeptService deptService;
@Override
public Result<SaTokenInfo> doLogin(LoginReq req) {
String key = SecureUtil.md5(req.getAccount()).substring(8,24);
String password = SecureUtil.aes(key.getBytes()).decryptStr(req.getPassword());
UserEntity user = userService.getOne(Wrappers.lambdaQuery(UserEntity.class).eq(UserEntity::getAccount, req.getAccount()).eq(UserEntity::getDelFlag, Constants.DEL_FLAG_0));
String pwdCiphertext = SecureUtil.md5(req.getAccount().concat(password).concat(user.getSalt()));
if(!pwdCiphertext.equals(user.getPassword())){
return Result.error(Constants.PASSWORD_ERROR_EXCEPTION, Constants.PASSWORD_ERROR_EXCEPTION_MESSAGE);
}
if(!user.getStatus().equals(Constants.STATUS_0)){
return Result.error(Constants.USER_DISABLE_EXCEPTION, Constants.USER_DISABLE_EXCEPTION_MESSAGE);
}
if(user.getIsDefaultPassword()){
return Result.error(Constants.DEFAULT_PASSWORD_EXCEPTION, Constants.DEFAULT_PASSWORD_EXCEPTION_MESSAGE);
}
StpUtil.login(user.getUserId());
saveUserSession(user);
return Result.ok(StpUtil.getTokenInfo());
}
@Override
public List<Tree<String>> getMenuInfo(String userId) {
return null;
}
@Override
public UserInfo getUserInfo(String userId) {
UserInfo userInfo = new UserInfo();
UserEntity user = userService.getOne(Wrappers.lambdaQuery(UserEntity.class).eq(UserEntity::getAccount, userId).eq(UserEntity::getDelFlag, Constants.DEL_FLAG_0));
userInfo.setUser(Converts.INSTANCE.toUserListResp(user));
DeptEntity dept = deptService.getOne(Wrappers.lambdaQuery(DeptEntity.class).eq(StrUtil.isNotBlank(user.getDeptId()), DeptEntity::getDeptId, user.getDeptId()).eq(DeptEntity::getDelFlag, Constants.DEL_FLAG_0));
userInfo.setDept(Converts.INSTANCE.toDeptResp(dept));
userInfo.setRoles(userRoleService.getRolesByUserId(userId));
userInfo.setPosts(userPostService.getPostsByUserId(userId));
return userInfo;
}
private void saveUserSession(UserEntity user){
StpUtil.getSession().set(user.getUserId(), user);
}
}

View File

@ -7,7 +7,6 @@ import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dite.znpt.constant.Message;
import com.dite.znpt.converts.Converts;
import com.dite.znpt.domain.entity.DeptEntity;
import com.dite.znpt.domain.entity.MenuEntity;
import com.dite.znpt.domain.vo.MenuReq;
import com.dite.znpt.domain.vo.MenuResp;
@ -30,6 +29,10 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, MenuEntity> impleme
@Override
public List<Tree<String>> tree(String menuName) {
List<MenuEntity> menuList = StrUtil.isBlank(menuName) ? this.baseMapper.downwardRecursionSelect(null) : this.baseMapper.upwardRecursionSelect(menuName);
return buildMenuTree(menuList);
}
public static List<Tree<String>> buildMenuTree(List<MenuEntity> menuList) {
//配置
TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
treeNodeConfig.setIdKey("menuId");

View File

@ -38,6 +38,9 @@ public class UserPostServiceImpl extends ServiceImpl<UserPostMapper, UserPostEnt
@Override
public List<PostResp> getPostsByUserId(String userId) {
List<String> postIds = this.list(Wrappers.lambdaQuery(UserPostEntity.class).eq(UserPostEntity::getUserId, userId)).stream().map(UserPostEntity::getPostId).toList();
if (CollUtil.isEmpty(postIds)) {
return new ArrayList<>();
}
List<PostEntity> posts= postService.listByIds(postIds).stream().filter(post -> Constants.STATUS_0.equals(post.getStatus())).toList();
return Converts.INSTANCE.toPostResp(posts);
}

View File

@ -40,6 +40,9 @@ public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRoleEnt
@Override
public List<RoleResp> getRolesByUserId(String userId) {
List<String> roleIds = this.list(Wrappers.lambdaQuery(UserRoleEntity.class).eq(UserRoleEntity::getUserId, userId)).stream().map(UserRoleEntity::getRoleId).toList();
if (CollUtil.isEmpty(roleIds)) {
return new ArrayList<>();
}
List<RoleEntity> roles = roleService.listByIds(roleIds).stream().filter(role -> Constants.DEL_FLAG_0.equals(role.getDelFlag()) && Constants.STATUS_0.equals(role.getStatus())).toList();
return Converts.INSTANCE.toRoleResp(roles);
}

View File

@ -0,0 +1,55 @@
package com.dite.znpt.web.controller;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.tree.Tree;
import com.dite.znpt.domain.Result;
import com.dite.znpt.domain.vo.LoginReq;
import com.dite.znpt.domain.vo.UserInfo;
import com.dite.znpt.service.AuthService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* @author Bear.G
* @date 2025/5/19/周一 14:32
* @description
*/
@Api(tags = "认证相关")
@RestController
@RequestMapping("/auth")
public class AuthController {
@Resource
private AuthService authService;
@ApiOperation(value = "登录",httpMethod = "POST", notes = "密码加密采用aes加密模式ECB填充方式PKCS#7加密传输加密密钥产生逻辑对账号做md5()计算然后取值8-24位。demo数据账号admin加密后的密码Csq+AVwlEzX3r5vfxL7d/g== 账号tino加密后的密码owbegSu4cMJRD4CiWO+WyQ==")
@PostMapping("/login")
public Result<SaTokenInfo> login(@Validated @RequestBody LoginReq req) {
return authService.doLogin(req);
}
@GetMapping("/userInfo")
@ApiOperation(value = "获取用户信息",httpMethod = "GET")
public Result<UserInfo> userInfo() {
return Result.ok(authService.getUserInfo(StpUtil.getLoginId().toString()));
}
@GetMapping("/menu")
@ApiOperation(value = "获取菜单",httpMethod = "GET")
public Result<List<Tree<String>>> getMenuInfo() {
return Result.ok(authService.getMenuInfo(StpUtil.getLoginId().toString()));
}
@ApiOperation(value = "登出",httpMethod = "POST")
@PostMapping("/logout")
public Result<SaTokenInfo> logout() {
authService.doLogout();
return Result.ok();
}
}

View File

@ -1,39 +0,0 @@
package com.dite.znpt.web.controller;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dite.znpt.constant.Constants;
import com.dite.znpt.domain.Result;
import com.dite.znpt.domain.entity.UserEntity;
import com.dite.znpt.domain.vo.LoginReq;
import com.dite.znpt.service.LoginService;
import com.dite.znpt.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @author Bear.G
* @date 2025/5/19/周一 14:32
* @description
*/
@Api(tags = "登录")
@RestController
public class LoginController {
@Resource
private LoginService loginService;
@ApiOperation(value = "登陆",httpMethod = "POST")
@PostMapping("/login")
public Result<SaTokenInfo> login(@Validated @RequestBody LoginReq req) {
return loginService.doLogin(req);
}
}