引言博文系列项目简介效果图开发环境数据表结构项目结构
后端结构前端结构 项目难点
后端难点前端难点 核心源码
前端源码配置登录页路由后端源码 下载链接博主寄语
引言博文系列Hello,我是Bug终结者,一名热爱后端Java的风趣且幽默的程序员~ 终于等到幸运的你~
快来发现我的宇宙哦~
深入浅出前后端分离系列第一篇 :前后端分离 — 深入浅出Spring Boot + Vue实现员工管理系统 Vue如此简单~
深入浅出前后端分离系列第二篇 :前后端分离 – 深入浅出 Spring Boot + Vue + ElementUI 实现相册管理系统【文件上传 分页 】 文件上传也不过如此~
深入浅出前后端分离系列第三篇 :前后端分离 – 深入浅出 Spring Boot + Vue 实现工程项目进度管理系统 Vue不过如此~
项目简介基于SpringBoot + Vue 实现后端分离项目,具体项目功能要求:
登录、注销、防跳墙功能
要求采用Spring Security安全框架完成
效果图 开发环境后端:Spring Boot + MyBatis + Maven
前端:Vue + ElementUI
工具:前端使用VSCode,后端使用IDEA
放松时间~
温馨提示:小看怡情,大看伤身 殺
数据表结构t_user用户表
CREATE TABLE `t_user` ( `noid` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '账户名', `password` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '账户密码', `realname` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '真实姓名', `role` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL, commit '用户角色' PRIMARY KEY (`noid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci项目结构 后端结构 前端结构 项目难点 后端难点
项目结构介绍
UserInfo,用户实体类,主要用于用户登录
SecretConfig:Spring Security核心配置类,该类中配置了用户的认证
CustoUserDetailsService:用户业务类,该类实现UserDetailsService类,主要用于查询数据库中是否存在输入的用户名并返回
Spring Security 安全框架
SecretConfig核心配置类:
package com.wanshi.config;
import com.wanshi.bean.ResultBean;
import com.wanshi.secret.CustomUserDetailsService;
import com.wanshi.utils.PbJsonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.*;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.expressionUrlAuthorizationConfigurer;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.web.cors.CorsUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecretConfig extends WebSecurityConfigurerAdapter {
//注入用户业务类,主要用于查询数据库中是否存在用户信息
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
//配置/api/login_local
$bg: #283443;
$light_gray: #fff;
$cursor: #fff;
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
.login-container .el-input input {
color: $cursor;
}
}
.login-container {
.box-change-locale-lang {
display: flex;
justify-content: flex-end;
padding: 20px 30px 0px;
}
.el-input {
display: inline-block;
height: 47px;
width: 85%;
input {
background: transparent;
border: 0px;
-webkit-appearance: none;
border-radius: 0px;
padding: 12px 5px 12px 15px;
color: $light_gray;
height: 47px;
caret-color: $cursor;
&:-webkit-autofill {
box-shadow: 0 0 0px 1000px $bg inset !important;
-webkit-text-fill-color: $cursor !important;
}
}
}
}
$bg: #2d3a4b;
$dark_gray: #889aa4;
$light_gray: #eee;
.login-container {
min-height: 100%;
width: 100%;
background-color: $bg;
overflow: hidden;
.login-form {
position: relative;
width: 520px;
max-width: 100%;
padding: 160px 35px 0;
margin: 0 auto;
overflow: hidden;
}
.el-form-item {
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(0, 0, 0, 0.1);
border-radius: 5px;
color: #454545;
padding-left:10px;
padding-right: 10px;
&.box-remember-pwd {
border: none;
background-color: rgba(0, 0, 0, 0);
.txt-remember-pwd {
padding-left: 30px;
color: #ffffff;
}
}
}
.tips {
font-size: 14px;
color: #fff;
margin-bottom: 10px;
span {
&:first-of-type {
margin-right: 16px;
}
}
}
.svg-container {
padding: 6px 5px 6px 15px;
color: $dark_gray;
vertical-align: middle;
width: 30px;
display: inline-block;
}
.icon1 {
font-size: 18px;
color: #eeeeee;
}
.title-container {
position: relative;
.title {
font-size: 26px;
color: $light_gray;
margin: 0px auto 40px auto;
text-align: center;
font-weight: bold;
}
@media only screen and (max-width: 470px) {
.title {
font-size: 22px;
}
}
}
.show-pwd {
position: absolute;
right: 4px;
top: 3px;
cursor: pointer;
user-select: none;
}
.thirdparty-button {
position: absolute;
right: 0;
bottom: 6px;
}
@media only screen and (max-width: 470px) {
.thirdparty-button {
display: none;
}
}
}
Index.vue
搜索
{{scope.row.crcc_name}}
{{scope.row.crcc_gender|filterCrccGender}}
{{scope.row.org_full_pathname}}
{{scope.row.department_name}}
{{scope.row.main_position_name}}
.box-main2{
display: flex;
.box-left1{
width: 420px;
padding:6px;
}
.box-right1{
flex: 7;
padding:10px;
.box-right1-in{
display: flex;
flex-direction: column;
.box-search{
display: flex;
padding:10px;
}
}
}
}
配置登录页路由
{
path: '/login-local',
meta: {pageTitle: '本地登录', leftMenuIndex: 'login-local'},
component: () => import('@/views/LoginLocal')
},
后端源码
CustomUserDetailsService.java
package com.wanshi.secret;
import com.wanshi.bean.UserInfo;
import com.wanshi.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserInfo param = new UserInfo();
param.setUsername(username);
UserInfo userInfo = userMapper.get(param);
if (userInfo == null) {
throw new UsernameNotFoundException("用户不存在");
}
// 得到用户角色
String role = userInfo.getRole();
// 角色集合
List authorities = new ArrayList<>();
// 角色必须以`ROLE_`开头,数据库中没有,则在这里加
authorities.add(new SimpleGrantedAuthority("ROLE_" + role));
return new User(
userInfo.getUsername(),
// 因为数据库是明文,所以这里需加密密码
new BCryptPasswordEncoder().encode(userInfo.getPassword()),
authorities
);
}
}
下载链接
本项目上传至GitEE码云进行项目管理,具体链接如下:
项目源码:前后端分离项目 – SpringBoot+SpringSecurity + Vue + ElementUI实现用户认证
建议使用SSH秘钥爬取源码
前端配置教程:使用GitEE拉取前端项目并配置,保证运行成功哦~
博主寄语该项目是一个基于SpringBoot+SpringSecurity + Vue + ElementUI实现用户认证实现的用户认证,项目逻辑稍微复杂,但只要你细心,坚持的敲上几遍,相信你的编程能力会极大的提升,加油~
若在本项目中遇到技术难题,可在下方评论区留言或私信我,授人以鱼不如授人以渔
如果你觉得博主写的不错的话,不妨给个一键三连,点击下方小拳头即可一键三连。



