后端实现

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/Shanghai

spring.datasource.username=root

spring.datasource.password=root

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.jpa.hibernate.ddl-auto=update

spring.jpa.properties.hibernate.show_sql=true

spring.jpa.properties.hibernate.format_sql=true

spring.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 id

User.java(续)

java

Copy 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

@Repository

public interface UserRepository extends JpaRepository {

User findByUsername(String username);

}

RoleRepository.java

java

Copy code

@Repository

public interface RoleRepository extends JpaRepository {

}

UserRoleRepository.java

java

Copy code

@Repository

public interface UserRoleRepository extends JpaRepository {

List findByUserId(Long userId);

}

6. 创建 Service

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

UserService.java

@Service

public class UserService {

@Autowired

private UserRepository userRepository;

@Autowired

private UserRoleRepository userRoleRepository;

public User findByUsername(String username) {

return userRepository.findByUsername(username);

}

public List findUserRolesByUserId(Long userId) {

return userRoleRepository.findByUserId(userId);

}

}

RoleService.java

@Service

public class RoleService {

@Autowired

private RoleRepository roleRepository;

}

UserRoleService.java

java

Copy code

@Service

public 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 findUserRolesByUserId(@PathVariable Long userId) {

return userService.findUserRolesByUserId(userId);

}

}

RoleController.java

@RestController

@RequestMapping("/api/role")

public class RoleController {

@Autowired

private RoleService roleService;

@GetMapping("")

public List 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

@EnableWebSecurity

public 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

Login.vue

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 文件,并添加以下代码:

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

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

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

@Configuration

@EnableWebSecurity

public 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方法来实现自定义的用户认证逻辑。

@Service

public 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 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组件代码:

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

13. 完整的UserForm.vue组件代码:

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

好文推荐

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: