springboot+springsecurity+vue+springdatajpa前后端分离员工管理系统

Posted 结构化思维wz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot+springsecurity+vue+springdatajpa前后端分离员工管理系统相关的知识,希望对你有一定的参考价值。

第一章、项目概述

人事管理系统是每个公司必备的管理系统,可以更方便的管理员工。

需求分析

hr实现对员工的增删改查,管理员实现对hr的更改。对员工进行搜索等功能。

总述

本项目是前后端分离项目,在服务器中运行。前端页面友好。

技术栈选择

  • 前端:vue3、vite2、axios、router、element UI 、nodejs
  • 后端:springboot、springsecurity、springdatajpa、maven、tomcat

环境介绍

  • 前端使用webstorm开发
  • 后端使用idea开发
  • 数据库使用mysql8.0
  • 可视化工具使用Navicat
  • JDK版本:15
  • maven版本:3.6
  • tomcat版本:9.0
  • npm版本:7.17

效果图展示

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

第二章、设计思路

该系统主要是前端设计页面接受后端的JSON数据,前后端所有数据除了登录页面使用key values 形式,其余全部使用JSON格式。后端使用springdatajpa自动生成的restful风格接口。前端通过axios发起请求获取接口数据。但是在开发中,我们需要克服跨域所带来的的问题。部署阶段就不存在跨域,因为我们会把前端打包到后端,一起部署。这样就不涉及到跨域问题了。当然也可以使用nigx进行代理。

数据库设计

在这里插入图片描述

数据表结构

员工表:

在这里插入图片描述

hr表:

在这里插入图片描述

角色表:

在这里插入图片描述

第三章、功能设计

  • hr登录
  • 权限鉴定
  • 对hr的增删改查
  • 对员工的增删改查

流程图

在这里插入图片描述

第四章、功能实现

后端功能实现

环境准备

在这里插入图片描述

添加springdata rest依赖

   <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
        </dependency>

目录结构

在这里插入图片描述

hr相关功能实现

登录功能

创建vhrdb数据库

在这里插入图片描述

配置jpa连接数据库

#配置数据库
spring.datasource.url=jdbc:mysql://localhost:3306/vhrdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456

#配置jpa
#1.jpa数据库
spring.jpa.database=mysql
#2.在控制台打印sql
spring.jpa.show-sql=true
#3.jpa数据库平台
spring.jpa.database-platform=mysql
#4.当对象改变更新表
spring.jpa.hibernate.ddl-auto=update
#5.指定方言!!!重要!!!
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
#.....



创建用户相关的表

  • 角色表

    package com.wz.vhrdb.entity;
    import javax.persistence.*;
    
    /**
     * @author: 王泽
     */
    
    @Entity
    @Table(name = "t_role")
    public class Role {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String name;
        private String nameZh;  //角色的中文名
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getNameZh() {
            return nameZh;
        }
    
        public void setNameZh(String nameZh) {
            this.nameZh = nameZh;
        }
    }
    
    
    
  • 用户表

    package com.wz.vhrdb.entity;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetails;
    import javax.persistence.*;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    
    /**
     * @author: 王泽
     */
    
    @Entity(name = "t_user")
    public class User implements UserDetails {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String username;
        private String password;
        private boolean accountNonExpired;
        private boolean accountNonLocked;
        private boolean credentialsNonExpired;
        private boolean enabled;
        @ManyToMany(fetch = FetchType.EAGER,cascade = CascadeType.PERSIST)
        private List<Role> roles;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public void setAccountNonExpired(boolean accountNonExpired) {
            this.accountNonExpired = accountNonExpired;
        }
    
        public void setAccountNonLocked(boolean accountNonLocked) {
            this.accountNonLocked = accountNonLocked;
        }
    
        public void setCredentialsNonExpired(boolean credentialsNonExpired) {
            this.credentialsNonExpired = credentialsNonExpired;
        }
    
        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
        }
    
        public List<Role> getRoles() {
            return roles;
        }
    
        public void setRoles(List<Role> roles) {
            this.roles = roles;
        }
    
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            List<SimpleGrantedAuthority> authorities = new ArrayList<>();
            for (Role role : getRoles()) {
                authorities.add(new SimpleGrantedAuthority(role.getName()));
            }
            return authorities;
        }
        @Override
        public String getPassword() {
            return password;
        }
    
        @Override
        public String getUsername() {
            return username;
        }
    
        @Override
        public boolean isAccountNonExpired() {
            return accountNonExpired;
        }
    
        @Override
        public boolean isAccountNonLocked() {
            return accountNonLocked;
        }
    
        @Override
        public boolean isCredentialsNonExpired() {
            return credentialsNonExpired;
        }
    
        @Override
        public boolean isEnabled() {
            return enabled;
        }
    }
    
    
  • 运行程序,创建表。

在这里插入图片描述

创建UserDao接口

package com.wz.vhrdb.dao;

import com.wz.vhrdb.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserDao extends JpaRepository<User,Long> {
    User findUserByUsername(String username);


}

创建UserService类

package com.wz.vhrdb.service;

import com.wz.vhrdb.dao.UserDao;
import com.wz.vhrdb.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

/**
 * @author: 王泽
 */

public class UserService implements UserDetailsService {
    @Autowired
    private UserDao userDao;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        final User user = userDao.findUserByUsername(username);
        if (user == null){
            throw new UsernameNotFoundException("用户不存在");
        }
        return user;
    }
}

配置springsecurity

package com.wz.vhrdb.config;

import com.wz.vhrdb.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author: 王泽
 */

public class SecurityConfig extends WebSecurityConfigurerAdapter {
   //密码不加密
    @Bean
    PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    //校验的数据源
    @Autowired
    UserService userService;
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService);
    }

    //角色关系
    @Bean
    RoleHierarchy roleHierarchy() {
        RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();
        hierarchy.setHierarchy("ROLE_admin > ROLE_user");
        return hierarchy;
    }

    //放行静态资源
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/js/**","/css/**","/image/**");
    }

    //配置拦截规则和表单配置
    //表单配置待完善
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**").hasRole("admin")//具备某个角色
                .antMatchers("/user/**").hasAnyRole("admin","user")
                .anyRequest().authenticated()//除了上述两个只要登录就能访问
                .and()
                .formLogin()
                .permitAll()
                .and()
                .csrf().disable();

    }
}

注册功能

直接在service中添加增添方法,jpa为我们提供了save

   //用户注册功能(增加用户)
    public User insertUser(User user) {
        return userDao.save(user);
    }
}

在controller中写接口

    /**
     * 新增用户 post /users
     */
    @PostMapping("")
    public User addUser(@RequestBody User user){
        return userService.insertUser(user);
    }

postman测试

{
    "username":"王泽",
    "password":"123",
    "accountNonExpired":true,
    "accountNonLocked":true,
    "credentialsNonExpired":true,
    "enabled":true,
    "roles":[{
        "name":"admin",
        "nameZh":"管理员"
    }]

}

我们可以给实体类设置一些默认值:

private boolean accountNonExpired =true;
    private boolean accountNonLocked = true;
    private boolean credentialsNonExpired =true;
    private boolean enabled =true;

测试:

package com.wz.vhrdb;

import com.wz.vhrdb.dao.UserDao;
import com.wz.vhrdb.entity.Role;
import com.wz.vhrdb.entity.User;
import com.wz.vhrdb.service.UserServiceImpl;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.ArrayList;
import java.util.List;

@SpringBootTest
class VhrdbApplicationTests {

    @Autowired
    UserServiceImpl userService;
    @Test
    void contextLoads() {
        User u1 = new User();
        u1.setUsername("liu");
        u1.setPassword("123");
//        u1.setAccountNonExpired(true);
//        u1.setAccountNonLocked(true);
//        u1.setCredentialsNonExpired(true);
//        u1.setEnabled(true);
        List<Role> rs1 = new ArrayList<>();
        Role r1 = new Role();
        r1.setName("ROLE_admin");
        r1.setNameZh("管理员");
        rs1.add(r1);
        u1.setRoles(rs1);
        userService.insertUser(u1);
        User u2 = new User();
        u2.setUsername("小刘");
        u2.setPassword("123");
//        u2.setAccountNonExpired(true);
//        u2.setAccountNonLocked(true);
//        u2.setCredentialsNonExpired(true);
//        u2.setEnabled(true);
        List<Role> rs2 = new ArrayList<>();
        Role r2 = new Role();
        r2.setName("ROLE_user");
        r2.setNameZh("普通用户");
        rs2.add(r2);
        u2.setRoles(rs2);
        userService.insertUser(u2);
    }
}

在这里插入图片描述

优化登录注册

主要问题有两方面:1.不能重复注册 2.密码加密问题

密码加密问题

首先我们注册的时候要添加密码加密

 //用户注册功能(增加用户)
    public User insertUser(User user) {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(10);
        user.setPassword(encoder.encode(user.getPassword()));
        return userDao.saveAndFlush(user);
    }

然后我们需要在springsecurity中配置

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
   //密码加密
   @Bean
   PasswordEncoder passwordEncoder() {
       return new BCryptPasswordEncoder(10);
   }

    //校验的数据源
    @Autowired
    UserServiceImpl userService;
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());
    以上是关于springboot+springsecurity+vue+springdatajpa前后端分离员工管理系统的主要内容,如果未能解决你的问题,请参考以下文章

Java 之SpringBoot+SpringSecurity+Vue实现后台管理系统的开发三系统权限

使用篇二SpringBoot集成SpringSecurity(22)

SpringBoot整合SpringSecurity

SpringBoot集成SpringSecurity+CAS

SpringBoot SpringSecurity 介绍(基于内存的验证)

Java 之SpringBoot+SpringSecurity+Vue实现后台管理系统的开发三系统权限