iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >SpringBoot和Vue.js怎么实现前后端分离的用户权限管理系统
  • 792
分享到

SpringBoot和Vue.js怎么实现前后端分离的用户权限管理系统

2023-07-05 20:07:30 792人浏览 安东尼
摘要

这篇文章主要介绍“SpringBoot和vue.js怎么实现前后端分离的用户权限管理系统”,在日常操作中,相信很多人在springBoot和Vue.js怎么实现前后端分离的用户权限管理系统问题上存在疑惑,小编查阅了各式资料,整理出简单好用的

这篇文章主要介绍“SpringBootvue.js怎么实现前后端分离的用户权限管理系统”,在日常操作中,相信很多人在springBoot和Vue.js怎么实现前后端分离的用户权限管理系统问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”SpringBoot和Vue.js怎么实现前后端分离的用户权限管理系统”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

后端实现

1. 数据库设计

我们需要设计两个表:用户表和角色表。

用户表

字段 类型 描述
id bigint(20) 用户 ID
username varchar(50) 用户名
passWord varchar(255) 密码
email varchar(50) 邮箱
phone varchar(20) 手机号码
create_by varchar(50) 创建人
create_time datetime 创建时间
update_by varchar(50) 最后修改人
update_time datetime 最后修改时间
status tinyint(1) 用户状态

角色表

字段 类型 描述
id bigint(20) 角色 ID
role_name varchar(50) 角色名称
create_by varchar(50) 创建人
create_time datetime 创建时间
update_by varchar(50) 最后修改人
update_time datetime 最后修改时间
status tinyint(1) 角色状态

用户角色表

字段 类型 描述
id bigint(20) ID
user_id bigint(20) 用户 ID
role_id bigint(20) 角色 ID
create_by varchar(50) 创建人
create_time datetime 创建时间
update_by varchar(50) 最后修改人
update_time datetime 最后修改时间
status tinyint(1) 状态

2. 创建 Maven 项目

使用 Maven 创建 Spring Boot 项目,引入 Spring Boot WEB、Spring Boot JPA、MySQL 和 Lombok 等依赖。可以使用以下命令创建 Maven 项目:

mvn archetype:generate -DgroupId=com.example -dartifactId=user-management -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

3. 配置数据库

在 application.properties 文件中添加以下配置:

spring.datasource.url=jdbc:Mysql://localhost:3306/user_management?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghaispring.datasource.username=rootspring.datasource.password=rootspring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.jpa.hibernate.ddl-auto=updatespring.jpa.properties.hibernate.show_sql=truespring.jpa.properties.hibernate.fORMat_sql=truespring.jpa.properties.hibernate.use_sql_comments=true

4. 创建实体类

创建 User、Role 和 UserRole 实体类,使用 Lombok 注解简化代码。具体代码如下:

User.java

@Data@Entity@Table(name = "user")public class User {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Long idUser.java(续)javaCopy code    private String username;    private String password;    private String email;    private String phone;    private String createBy;    private Date createTime;    private String updateBy;    private Date updateTime;    private Boolean status;}

Role.java

@Data@Entity@Table(name = "role")public class Role {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Long id;    private String roleName;    private String createBy;    private Date createTime;    private String updateBy;    private Date updateTime;    private Boolean status;}

UserRole.java

@Data@Entity@Table(name = "user_role")public class UserRole {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Long id;    private Long userId;    private Long roleId;    private String createBy;    private Date createTime;    private String updateBy;    private Date updateTime;    private Boolean status;}

5. 创建 Repository

创建 UserRepository、RoleRepository 和 UserRoleRepository,用于操作数据库。

UserRepository.java

@Repositorypublic interface UserRepository extends JpaRepository<User, Long> {    User findByUsername(String username);}

RoleRepository.java

@Repositorypublic interface RoleRepository extends JpaRepository<Role, Long> {}

UserRoleRepository.java

@Repositorypublic interface UserRoleRepository extends JpaRepository<UserRole, Long> {    List<UserRole> findByUserId(Long userId);}

6. 创建 Service

创建 UserService、RoleService 和 UserRoleService,用于处理业务逻辑。

UserService.java

@Servicepublic class UserService {    @Autowired    private UserRepository userRepository;    @Autowired    private UserRoleRepository userRoleRepository;    public User findByUsername(String username) {        return userRepository.findByUsername(username);    }    public List<UserRole> findUserRolesByUserId(Long userId) {        return userRoleRepository.findByUserId(userId);    }}

RoleService.java

@Servicepublic class RoleService {    @Autowired    private RoleRepository roleRepository;}

UserRoleService.java

@Servicepublic class UserRoleService {    @Autowired    private UserRoleRepository userRoleRepository;}

7. 创建 Controller

创建 UserController、RoleController 和 UserRoleController,用于处理请求。

UserController.java

@RestController@RequestMapping("/api/user")public class UserController {    @Autowired    private UserService userService;    @GetMapping("/{username}")    public User findByUsername(@PathVariable String username) {        return userService.findByUsername(username);    }    @GetMapping("/{userId}/roles")    public List<UserRole> findUserRolesByUserId(@PathVariable Long userId) {        return userService.findUserRolesByUserId(userId);    }}

RoleController.java

@RestController@RequestMapping("/api/role")public class RoleController {    @Autowired    private RoleService roleService;    @GetMapping("")    public List<Role> findAll() {        return roleService.findAll();    }}

UserRoleController.java

@RestController@RequestMapping("/api/userRole")public class UserRoleController {    @Autowired    private UserRoleService userRoleService;}

8. 启动应用

使用 Maven 命令 mvn spring-boot:run 启动应用,或者直接运行 UserManagementApplication 类。

9. 完整的SecurityConfig.java:

@Configuration@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter {    @Autowired    private UserDetailsServiceImpl userDetailsService;    @Autowired    private JwtAuthenticationEntryPoint unauthorizedHandler;    @Bean    public JwtAuthenticationFilter jwtAuthenticationFilter() {        return new JwtAuthenticationFilter();    }    @Override    public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {        authenticationManagerBuilder                .userDetailsService(userDetailsService)                .passwordEncoder(passwordEncoder());    }    @Bean(BeanIds.AUTHENTICATION_MANAGER)    @Override    public AuthenticationManager authenticationManagerBean() throws Exception {        return super.authenticationManagerBean();    }    @Bean    public PasswordEncoder passwordEncoder() {        return new BCryptPasswordEncoder();    }    @Override    protected void configure(httpsecurity Http) throws Exception {        http                .cors()                    .and()                .csrf()                    .disable()                .exceptionHandling()                    .authenticationEntryPoint(unauthorizedHandler)                    .and()                .sessionManagement()                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)                    .and()                .authorizeRequests()                    .antMatchers("/api/auth/**")                        .permitAll()                    .anyRequest()                        .authenticated();        http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);    }}

其中,JwtAuthenticationFilter是前面提到的JWT认证过滤器,UserDetailsServiceImpl是实现了Spring Security的UserDetailsService接口的用户服务类,JwtAuthenticationEntryPoint是未经授权时抛出的异常处理程序。配置类中的configure方法配置了授权规则,访问“/api/auth/**”路径下的接口不需要认证即可访问,其他所有请求都需要认证后才能访问。同时,我们也添加了JWT认证过滤器。

前端实现

1. 创建 Vue.js 项目

使用 Vue CLI 创建项目:

vue create user-management

2. 添加依赖

在 package.JSON 中添加以下依赖:

{  "dependencies": {    "axiOS": "^0.21.1",    "element-plus": "^1.0.2-beta.55",    "vue": "^2.6.12",    "vue-router": "^3.5.1"  }}

然后执行 npm install 安装依赖。

3. 配置 Axios

在 src/main.js 中添加以下代码:

import axios from 'axios'axios.defaults.baseURL = 'http://localhost:8080/api'Vue.prototype.$http = axios

4. 创建路由

在 src/router/index.js 中添加以下代码:

import Vue from 'vue'import VueRouter from 'vue-router'import Home from '../views/Home.vue'import Login from '../views/Login.vue'Vue.use(VueRouter)const routes = [  {    path: '/',    name: 'Home',    component: Home  },  {    path: '/login',    name: 'Login',    component: Login  }]const router = new VueRouter({  mode: 'history',  base: process.env.BASE_URL,  routes})export default router

5. 创建页面

在 src/views 目录下创建以下页面:

Home.vue

<template>  <div>    <h2>用户管理</h2>    <table>      <thead>        <tr>          <th>用户名</th>          <th>邮箱</th>          <th>手机号码</th>          <th>操作</th>        </tr>      </thead>      <tbody>        <tr v-for="user in users" :key="user.id">          <td>{{ user.username }}</td>          <td>{{ user.email }}</td>          <td>{{ user.phone }}</td>          <td>            <button @click="editUser(user)">编辑</button>            <button @click="deleteUser(user)">删除</button>          </td>        </tr>      </tbody>    </table>  </div></template><script>export default {  name: 'Home',  data() {    return {      users: []    }  },  mounted() {    this.loadUsers()  },  methods: {    loadUsers() {      this.$http.get('/user')        .then(response => {          this.users = response.data        })        .catch(error => {          console.log(error)        })    },    editUser(user) {      console.log(user)    },    deleteUser(user) {      console.log(user)    }  }}</script>

Login.vue

<template>  <div>    <h2>登录</h2>    <form @submit.prevent="login">      <div>        <label>用户名:</label>        <input type="text" v-model="username" />      </div>      <div>        <label>密码:</label>        <input type="password" v-model="password" />      </div>      <button type="submit">登录</button>    </form>  </div></template><script>export default {  name: 'Login',  data() {    return {      username: '',      password: ''    }  },  methods: {    login() {      const params = {        username: this.username,        password: this.password  }  this.$http.post('/login', params)    .then(response => {      console.log(response)    })    .catch(error => {      console.log(error)    })}}}</script>

6. 添加 Element UI 组件

在 src/main.js 中添加以下代码:

import ElementPlus from 'element-plus'import 'element-plus/dist/index.CSS'Vue.use(ElementPlus)

7. 运行项目

在项目根目录下执行以下命令运行项目:

npm run serve

然后在浏览器中访问 http://localhost:8080 查看效果。

以上代码只是简单地实现了用户列表的显示以及登录功能的实现,还需要进一步完善和优化。同时,还需要在后端实现相应的接口。

8. 添加路由

在 src/router/index.js 中添加以下代码:

import Vue from 'vue'import VueRouter from 'vue-router'import Login from '../views/Login.vue'import UserList from '../views/UserList.vue'Vue.use(VueRouter)const routes = [  {    path: '/',    redirect: '/login'  },  {    path: '/login',    name: 'Login',    component: Login  },  {    path: '/userlist',    name: 'UserList',    component: UserList,    meta: {      requireAuth: true    }  }]const router = new VueRouter({  mode: 'history',  base: process.env.BASE_URL,  routes})export default router

其中,meta 属性中的 requireAuth 表示该路由需要登录才能访问。

9. 添加登录拦截

在 src/main.js 中添加以下代码:

router.beforeEach((to, from, next) => {  if (to.meta.requireAuth && !localStorage.getItem('token')) {    next({      path: '/login',      query: { redirect: to.fullPath }    })  } else {    next()  }})

这段代码的作用是,在用户访问需要登录才能访问的路由时,检查用户是否已登录。如果用户未登录,则跳转到登录页面,并将目标路由的路径保存到查询参数中,以便用户登录成功后自动跳转到目标路由。

10. 添加用户服务

在 src/services 目录下创建 UserService.js 文件,并添加以下代码:

import axios from 'axios'const API_URL = '/api/users/'class UserService {  getUsers () {    return axios.get(API_URL)  }  getUser (id) {    return axios.get(API_URL + id)  }  createUser (data) {    return axios.post(API_URL, data)  }  updateUser (id, data) {    return axios.put(API_URL + id, data)  }  deleteUser (id) {    return axios.delete(API_URL + id)  }}export default new UserService()

该文件定义了一个 UserService 类,用于向后端发送请求,获取用户数据。其中,API_URL 表示后端 API 的根路径,getUsers、getUser、createUser、updateUser 和 deleteUser 方法分别对应获取用户列表、获取单个用户、创建用户、更新用户和删除用户。

11. 添加用户列表页面

在 src/views 目录下创建 UserList.vue 文件,并添加以下代码:

<template>  <div>    <h2>用户列表</h2>    <div class="mb-3">      <router-link to="/user/add" class="btn btn-primary">添加用户</router-link>    </div>    <table class="table table-striped">      <thead>        <tr>          <th>用户名</th>          <th>邮箱</th>          <th>角色</th>          <th>操作</th>        </tr>      </thead>      <tbody>        <tr v-for="user in userList" :key="user.id">          <td>{{ user.username }}</td>          <td>{{ user.email }}</td>          <td>{{ user.roles.map(role => role.name).join(', ') }}</td>          <td>            <router-link :to="'/user/edit/' + user.id" class="btn btn-primary">编辑</router-link>            <button class="btn btn-danger" @click="deleteUser(user.id)">删除</button>          </td>        </tr>      </tbody>    </table>  </div></template><script>import axios from "axios";export default {  data() {    return {      userList: [],    };  },  methods: {    fetchUserList() {      axios.get("/api/private/users").then((response) => {        this.userList = response.data;      });    },    deleteUser(id) {      if (confirm("确定删除该用户吗?")) {        axios.delete(`/api/private/users/${id}`).then(() => {          this.fetchUserList();        });      }    },  },  mounted() {    this.fetchUserList();  },};</script>

这个文件中,我们使用了vue-router和axios库。在fetchUserList方法中,我们使用axios库发起了一个GET请求来获取用户列表。在deleteUser方法中,我们使用axios库发起了一个DELETE请求来删除用户。

接下来我们将完成系统的权限控制部分。在Spring Security中,权限控制通常通过定义安全配置类来实现。

首先,我们需要创建一个实现了WebSecurityConfigurer接口的安全配置类SecurityConfig。在这个类中,我们可以配置用户认证和授权规则。

@Configuration@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter {     @Autowired    private UserDetailsService userDetailsService;     @Override    protected void configure(HttpSecurity http) throws Exception {        http.csrf().disable()                .authorizeRequests()                .antMatchers("/api/public/**").permitAll()                .antMatchers("/api/private/**").authenticated()                .and().formLogin()                .loginPage("/login")                .permitAll()                .defaultSuccessUrl("/")                .and().loGout().logoutUrl("/logout").logoutSuccessUrl("/login").invalidateHttpSession(true);    }     @Override    protected void configure(AuthenticationManagerBuilder auth) throws Exception {        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());    }     @Bean    public PasswordEncoder passwordEncoder() {        return new BCryptPasswordEncoder();    }}

在上述代码中,我们配置了以下规则:

  • 所有以/api/public开头的请求都不需要认证即可访问。

  • 所有以/api/private开头的请求都需要认证才能访问。

  • 登录页面为/login,登录成功后默认跳转到根路径/。

  • 注销路径为/logout,注销成功后跳转到登录页面。

  • 在AuthenticationManagerBuilder中指定了用户认证服务和密码加密方式。

为了实现用户认证,我们需要创建一个实现了UserDetailsService接口的用户认证服务。UserDetailsService是一个Spring Security的核心接口,用于查询用户信息。我们可以通过重写该接口的loadUserByUsername方法来实现自定义的用户认证逻辑。

@Servicepublic class UserDetailsServiceImpl implements UserDetailsService {     @Autowired    private UserRepository userRepository;     @Override    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {        User user = userRepository.findByUsername(username);        if (user == null) {            throw new UsernameNotFoundException("用户不存在");        }        List<SimpleGrantedAuthority> authorities = user.getRoles().stream()                .map(role -> new SimpleGrantedAuthority(role.getName()))                .collect(Collectors.toList());        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),                authorities);    }}

在上述代码中,我们通过注入UserRepository来查询用户信息。然后,我们将查询到的用户角色信息转换为Spring Security的授权信息,并返回一个UserDetails对象。

至此,我们已经完成了用户认证和权限控制的实现。通过这个系统,我们可以实现用户登录、注销和权限控制等基础功能。

12. 完整的AddUser.vue组件代码:

<template>  <div>    <h3>Add User</h3>    <form>      <div class="form-group">        <label for="username">Username</label>        <input type="text" class="form-control" id="username" v-model="user.username" required>      </div>      <div class="form-group">        <label for="email">Email</label>        <input type="email" class="form-control" id="email" v-model="user.email" required>      </div>      <div class="form-group">        <label for="password">Password</label>        <input type="password" class="form-control" id="password" v-model="user.password" required>      </div>      <div class="form-group">        <label for="roles">Roles</label>        <select multiple class="form-control" id="roles" v-model="user.roles">          <option v-for="role in roles" :key="role.id" :value="role">{{ role.name }}</option>        </select>      </div>      <button type="button" class="btn btn-primary" @click="addUser">Add User</button>    </form>  </div></template><script>import axios from 'axios';export default {  name: 'AddUser',  data() {    return {      user: {        username: '',        email: '',        password: '',        roles: []      },      roles: []    }  },  created() {    axios.get('/api/roles')      .then(response => {        this.roles = response.data;      })      .catch(error => {        console.log(error);      });  },  methods: {    addUser() {      axios.post('/api/users', this.user)        .then(response => {          this.$router.push({ name: 'UserList' });        })        .catch(error => {          console.log(error);        });    }  }}</script><style scoped>.form-group {  margin-bottom: 1rem;}</style>

在这个组件中,我们使用了Bootstrap的样式来美化表单。我们从后端获取了所有的角色列表,将其渲染到了下拉列表中。同时,我们绑定了一个addUser方法,在点击“Add User”按钮时将用户信息提交到后端创建一个新用户。13. 完整的UserForm.vue组件代码:

<template>  <div>    <form>      <div class="form-group">        <label for="username">Username</label>        <input type="text" class="form-control" id="username" v-model="user.username" required>      </div>      <div class="form-group">        <label for="email">Email</label>        <input type="email" class="form-control" id="email" v-model="user.email" required>      </div>      <div class="form-group">        <label for="password">Password</label>        <input type="password" class="form-control" id="password" v-model="user.password" required>      </div>      <div class="form-group">        <label for="roles">Roles</label>        <select multiple class="form-control" id="roles" v-model="user.roles">          <option v-for="role in roles" :key="role.id" :value="role">{{ role.name }}</option>        </select>      </div>      <button type="button" class="btn btn-primary" @click="submitForm">{{ submitButtonLabel }}</button>    </form>  </div></template><script>import axios from 'axios';export default {  name: 'UserForm',  props: {    user: {      type: Object,      default: () => {        return {          username: '',          email: '',          password: '',          roles: []        };      }    },    roles: {      type: Array,      default: () => {        return [];      }    },    submitButtonLabel: {      type: String,      default: 'Submit'    },    onSubmit: {      type: Function,      default: () => {        console.log('Submit function not provided');      }    }  },  methods: {    submitForm() {      this.onSubmit(this.user);    }  }}</script><style scoped>.form-group {  margin-bottom: 1rem;}</style>

在这个组件中,我们使用了Bootstrap的样式来美化表单。我们从父组件中传递了一个user对象、roles数组和submitButtonLabel属性,分别用于渲染表单元素和提交按钮。同时,我们使用了props属性来声明这些属性。最后,我们绑定了一个submitForm方法,在点击提交按钮时将用户信息传递给父组件的onSubmit方法处理。

到此,关于“SpringBoot和Vue.js怎么实现前后端分离的用户权限管理系统”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: SpringBoot和Vue.js怎么实现前后端分离的用户权限管理系统

本文链接: https://www.lsjlt.com/news/354973.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作