网页设计培训心得南阳本地网络推广优化公司
先说一下遇到的问题吧:
很显然,我要用security实现认证授权,但是用过security的小伙伴应该都知道,security做登录,需要实现UserDetailsService这个接口,但是这个接口只能接收一个参数,但是我在最开始设计这个数据库的时候,是设计了三张用户表,分别是admin,teacher,student,那么现在该如何去区分当前登录的是哪个表呢?
废话不多说,先上我第一种解决方案,我是这样解决的:
在UserDetailServiceImpl实现类,去分别查询三张表,如果哪个表查到了,就说明是哪个表的用户在登录,听上去是没问题的吧,我开始也是这样想的,但是我们换种角度去想,假如我三张表里面有相同的账号,这个是可以存在的吧,那么这个时候,就有可能会用学生账号去登录管理员系统,这是相当严重的一个bug
那么如何去解决呢?
我们可以在前端做一些歪门邪道,只需要在当前登录的用户名,后面拼接上用户角色字段就行了,然后在后端去截取这个角色字符串,那么现在我的代码就是这样写的
@Service @Slf4j public class UserDetailsImpl implements UserDetailsService {@Resourceprivate AdminMapper adminMapper;@Resourceprivate TeacherMapper teacherMapper;@Resourceprivate StudentMapper studentMapper;private static final Map<String, RoleEnum> ROLE_MAP = Stream.of(RoleEnum.values()).collect(Collectors.toMap(role -> role.name(), Function.identity()));@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {log.info("正在加载用户: {}", username);String[] parts = username.split("_");if (parts.length < 2 || !ROLE_MAP.containsKey(parts[1])) {log.warn("用户名格式不正确或角色不存在: {}", username);throw new UsernameNotFoundException("用户名格式不正确或角色不存在: " + username);}//截取后的usernameString account = parts[0];//截取后的roleString role = parts[1];log.info("用户角色: {}", role);return switch (ROLE_MAP.get(role)) {case ADMIN -> handleAdminLogin(account);case TEACHER -> handleTeacherLogin(account);case STUDENT -> handleStudentLogin(account);default -> {log.warn("未找到用户: {}", username);throw new UsernameNotFoundException("未找到用户: " + username);}};}private UserDetails handleAdminLogin(String account) {Admin admin = adminMapper.selectByUsername(account);if (admin != null) {log.info("找到 Admin 用户: {}", admin.getUsername());return new SecurityUser(mapToAccount(admin));}throw new UsernameNotFoundException("未找到用户: " + account);}private UserDetails handleTeacherLogin(String account) {Teacher teacher = teacherMapper.selectByUsername(account);if (teacher != null) {log.info("找到 Teacher 用户: {}", teacher.getUsername());return new SecurityUser(mapToAccount(teacher));}throw new UsernameNotFoundException("未找到用户: " + account);}private UserDetails handleStudentLogin(String account) {Student student = studentMapper.selectByUsername(account);if (student != null) {log.info("找到 Student 用户: {}", student.getUsername());return new SecurityUser(mapToAccount(student));}throw new UsernameNotFoundException("未找到用户: " + account);}/*** 将 Admin、Teacher 或 Student 对象映射为 Account 对象*/private Account mapToAccount(Object user) {Account account = new Account();if (user instanceof Admin) {Admin admin = (Admin) user;account.setId(admin.getId());account.setUsername(admin.getUsername());account.setPassword(admin.getPassword());account.setAvatar(admin.getAvatar());account.setRole(admin.getRole());} else if (user instanceof Teacher) {Teacher teacher = (Teacher) user;account.setId(teacher.getId());account.setUsername(teacher.getUsername());account.setPassword(teacher.getPassword());account.setAvatar(teacher.getAvatar());account.setRole(teacher.getRole());} else if (user instanceof Student) {Student student = (Student) user;account.setId(student.getId());account.setUsername(student.getUsername());account.setPassword(student.getPassword());account.setAvatar(student.getAvatar());account.setRole(student.getRole());}return account;} }
所以有时候,换一个角度去思考问题,会少走很多弯路,还有就是最开始设计数据库的时候,一定要为后面的操作做好铺垫。