文章目录
基于Security的用户登录功能及用户注册功能
1 用户登录功能实现-基于内置账户的登录
1.1 客户端
PS:
-
SpringSecurity获取请求的方式为
getParameter
该方式只能获取from Date
||query Sting
两种 -
但是此时前端我们发送的请求为
pay load
请求,该请求是将参数放在请求体里面的,getParameter
无法获取该种请求-
解决方法
- 修改前端请求为from Date请求
- 修改后端接受方法
-
此处我们用第一种用方式qs序列化,将payload转化为fromDate请求
-
1.1.1 Index.vue页面登陆和注册按钮,及登录后查看个人下拉表单和购物车按钮的实现
<el-header>
<div class="header-div">
<div class="logo-div">
<img:src="require('@/assets/logo.png')"style="width:440px;height:130px;border:0px solid red ;"/>
</div>
<div class="personal-div">
<div v-if="false">
<el-button type="success" plain @click="$router.push('/login')">登录</el-butto
<el-button type="warning" plain>注册</el-button>
</div>
<div v-if="true">
<el-dropdown>
<el-button type="warning" icon="el-icon-user">
小明<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>个人中心</el-dropdown-item>
<el-dropdown-item>查看订单</el-dropdown-item>
<el-dropdown-item>退出</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-badge :value="12" class="item">
<el-button type="success" icon="el-icon-shopping-cart-full" @click="$router.push('/showCar')">购物车</el-button>
</el-badge>
</div>
</div>
</div>
</el-header>
1.1.2 Login.vue页面的实现
- 配置路由
import Login from "../views/Login.vue"
const routes = [
{
path: "/login",
name: "login",
component: Login,
},
];
- Login.vue页面UI显示
<template>
<div class="win-logoin">
<div class="container" id="login-container">
<img :src="require('@/assets/logo.png')" style="width:440px;height:130px;border:0px solid red ;"/>
<div class="form">
<div class="login-input">
<label>用户名:</label>
<input type="text" v-model="user.username" />
</div>
<div class="login-input">
<label>密 码:</label>
<input type="password" v-model="user.password" />
</div>
<div class="login-button">
<button @click.prevent="login">登录</button>
</div>
</div>
</div>
</div>
</template>
<script>
</script>
<style scoped>
.win-logoin {
position: absolute;
top: 0px;
bottom: 0px;
margin: 0px;
left: 0px;
right: 0px;
padding: 0px;
display: flex;
background:url( "../assets/images/login/backgroundlogin.png");
/*设置弹性布局*/
flex-direction: row;
/*设置水平方向*/
justify-content: center;
/*根据direction的方向设置居中*/
align-items: center;
/*根据direction的反方向设置居中*/
}
.container {
width: 700px;
height: 400px;
border-radius: 5px;
box-shadow: 0px 0px 10px 5px black;
display: flex;
background:url( "../assets/images/login/background.png");
/*设置弹性布局*/
flex-direction: column;
}
.form{
margin-left: 28%;
}
.login-input {
position: relative;
width: 300px;
height: 50px;
border: 0px solid red;
margin: 5px 0;
}
.login-input>label {
box-sizing: border-box;
position: absolute;
border: 0px solid red;
width: 80px;
height: 50px;
line-height: 50px;
letter-spacing: 2px;
padding-left: 10px;
color: #666666;
}
.login-input>input {
box-sizing: border-box;
border-radius: 5px;
border: 1px solid #dddddd;
padding-left: 80px;
outline: none;
font-size: 18px;
width: 100%;
height: 100%;
}
.login-button {
position: relative;
width: 300px;
height: 50px;
margin: 15px 0;
}
.login-button>button {
border: 0;
width: 100%;
height: 100%;
border-radius: 5px;
border: 1px solid #dddddd;
outline: none;
background-color: white;
letter-spacing: 15px;
padding-left: 15px;
color: #666666;
font-size: 18px;
}
.login-button>button:hover {
cursor: pointer;
background-color: cornflowerblue;
color: white;
}
.login-button>button:active {
font-weight: bold;
outline: none;
border: 0;
box-shadow: 0px 0px 8px 1px #7088ff;
}
</style>
1.1.3 向后端传递数据,及做出相应处理
export default {
name: "Login",
data() {
return {
user: {},//当前登录的对象
};
},
methods: {
//登录方法
login() {
//加载条
const loading =this.$loading({
lock:true,
text:"登陆中,请稍后",
spinner:"el-icon-loading",
background: "rgba(0,0,0,,0.7)"
});
this.$axios
.post('login', this.$qs.stringify(this.user))
.then(response=>{
loading.close();
let result=response.data;
if(result.success){
let curUser =result.data;
//弹出提示框
this.$swal.fire({
icon: 'success',
title: result.message,
showConfirmButton: false,
timer:1000,
didClose:()=>{
this.$router.push("/");
}
});
}else{
this.$swal.fire({
icon: 'error',
title: result.message,
showConfirmButton: false,
timer: 1000,
didClose: () => {
alert("弹窗已关闭");
}
});
}
})
.catch(error=>{
alert(error)
})
}
}
};
1.2 服务端
1.2.1 引入SpringSecurity依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
1.2.2 配置SpringSecurity
- 处理器执行优先级高于控制器
/**
* SpringSecurity配置类
*/
@Configuration
public class SecurityConfig {
/**
* 用于拦截请求,并对请求进行处理
* @param httpSecurity
* @return SecurityFilterChain:Security过滤器链
*/
@Bean
@Autowired
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
//security默认禁止跨域请求
.cors()
.and()
.csrf().disable()//禁止跨域伪造访问
.authorizeRequests()//获得请求
.antMatchers("/book/*")
.permitAll()//无需认证直接访问
.anyRequest()//所有请求
.authenticated()//必须认证才能访问
.and()
//配置登陆页form表单
.formLogin()//配置表单
.loginProcessingUrl("/login")//使用重定向方式配置登陆处理器的url地址,该地址所对应处理类由SpringSecurity提供
.loginPage("http://localhost:8080/#/login")//配置登陆页
.successHandler(new LoginSuccessHandler())//成功处理器,成功后跳转到指定处理器
.failureHandler(new LoginFailureHandler())
;
return httpSecurity.build();//获得securityFilterChain的实现类对象并返回
}
}
1.2.3 添加登录成功和登陆失败Handler
- 登陆失败Handler
/**
* 登陆失败处理器,该处理器实现AuthenticationFailureHandler
* 当用户登陆成功后会自动执行该处理器里的onAuthenticationFailure方法
*/
public class LoginFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
response.setContentType("application/json;charset=utf-8");
response.getWriter().println("失败");
}
}
- 登陆成功Handler
/**
* 登陆成功处理器,该处理器实现AuthenticationSuccessHandler
* 当用户登陆成功后会自动执行该处理器里的onAuthenticationSuccess方法
*/
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//设置响应类型及编码集
response.setContentType("application/json;charset=utf-8");
response.getWriter().println("成功");
}
}
2 用户登录功能实现-基于数据库的登录
2.1 客户端
2.1.1 登录成功将后端传来的用户信息做处理
客户端用sessionStorage存储时智能字符串,需要用
JSON.stringify()
转化为字符串
if(result.success){//登陆成功
let curUser =result.data;
//弹出提示框
this.$swal.fire({
icon: 'success',
title: result.message,
showConfirmButton: false,
timer:1000,
didClose:()=>{
//将当前用户登陆者信息存入sessionStorage
let curUser=result.data;
let curUserInfo = JSON.stringify(curUser)
window.sessionStorage.setItem("curUserInfo",curUserInfo);
this.$router.push("/");
}
});
}
2.1.2 进入主页面做的处理
<div class="personal-div">
<div v-if="curUserInfo ==null?true:false">
<el-button type="success" plain @click="$router.push('/login')">登录</el-button>
<el-button type="warning" plain>注册</el-button>
</div>
<div v-if="curUserInfo ==null?false:true">
<el-dropdown>
<el-button type="warning" icon="el-icon-user">
{{curUserInfo.user_name}}
<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>个人中心</el-dropdown-item>
<el-dropdown-item>查看订单</el-dropdown-item>
<el-dropdown-item>退出</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-badge :value="12" class="item">
<el-button type="success" icon="el-icon-shopping-cart-full" @click="$router.push('/showCar')">购物车</el-button>
</el-badge>
</div>
</div>
2.1.3 从主页面获取用户信息
data(){
return{
curUserInfo:null,//用户信息
}
},
methods: {
//获取用户信息
getCurUserInfo(){
//从sessionStorage获取用户信息,并转化为Json形式
this.curUserInfo= JSON.parse(window.sessionStorage.getItem("curUserInfo"));
},
created(){
this.getCurUserInfo();
}
2.2 服务端
2.2.1 声明UserDetailsService对象并注入进认证管理器
将用户信息提交给认证处理器,并设置密码加密
@Autowired
private UserDetailsService userDetailsService;
/**
* 注入认证处理器
* @param builder
* @throws Exception
*/
@Autowired
public void registerProvider(AuthenticationManagerBuilder builder) throws Exception{
builder.userDetailsService(userDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
}
2.2.2 创建model-userInfo
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserInfo implements Serializable {
private Integer user_id;
private String user_name;
private String user_password;
private String user_email;
private Date user_birthday;
private String user_hobbys;
private Integer user_sex;
private String user_address;
private Integer user_status;
}
2.2.3 创建UserMapper
根据用户名查询用户信息
@Repository
public interface UserMapper {
/**
*
* 根据用户名获得用户对象
* @param username
* @return
*/
@Select("select * from tbl_user where user_name=#{username}")
public UserInfo getUserByUsername(String username);
}
2.2.3 创建UserDetailsService实现类UserDetailsServiceImpl
将用户信息封装到UserDetails对象中(此处返回UserDetails的实现类User(该User是security提供的))
/**
* 处理认证逻辑的类
* + 该类需要重写接口中的loadUserByUsername方法根据用户名获得用户对象
*/
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Resource
private UserMapper userMapper;
/**
* 1.根据用户名获得用户信息
* 2.将用户信息认证需要的数据封装到UserDetails的实现类对象中(UserInfo)
* 3.将封装好的认证信息提交给SpringSecurity进行认证
*
* @param username
* @return
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserInfo userInfo = userMapper.queryUserByUserName(username);
//设置当前账户权限集合
//判断用户名是否正确
if (userInfo == null) {//用户不存在
return null;
}
if (userInfo.getUser_status() == -1) {//用户被冻结
return null;
}
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
User user = new User(
userInfo.getUser_name(),
userInfo.getUser_password(),
true,//账户是否启用
true,//账户是否过期
true,//凭证是否过期
userInfo.getUser_status() == 0 ? true : false,//账户是否被锁定
authorities//账户拥有权限集合
);
return user;
}
}
2.2.4 创建公共类-CurUserInfo
存放当前用户信息
/**
* 当前登陆用户对象
* 存放当前用户信息
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CurUserInfo {
private Integer user_id;
private String user_name;
}
2.2.5 修改Service层的User对象的内容
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
//为保护密码信息,将密码取出来后设为null
String password = userInfo.getUser_password();
userInfo.setUser_password(null);
User user = new User(
JSONObject.toJSONString(userInfo),//将用户信息对象转化为json串存放到username中
password,
true,//账户是否启用
true,//账户是否过期
true,//凭证是否过期
userInfo.getUser_status() == 0 ? true : false,//账户是否被锁定
authorities//账户拥有权限集合
);
2.2.6 修改登陆成功的Handler
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//设置响应类型及编码集
response.setContentType("application/json;charset=utf-8");
//获得认证对象获得认证主体,主体式User对象
User user= (User) authentication.getPrincipal();
//将用户名转化为UserInfo对象
//user.getUsername存放有用户信息,将该信息转换为UserInfo对象
UserInfo userInfo = JSONObject.parseObject(user.getUsername(), UserInfo.class);
//将userInfo中的数据转存到CurUserInfo中
CurUserInfo curUserInfo=new CurUserInfo();
curUserInfo.setUser_id(userInfo.getUser_id());
curUserInfo.setUser_name(userInfo.getUser_name());
Result result =Result.success("登陆成功",curUserInfo);
response.getWriter().println(JSONObject.toJSONString(result));
}
}
3 登陆失败和退出账号功能
3.1 登陆失败的处理
UsernameNotFoundException
:用户名不存在错误(默认禁用)
BadCredentialsException
:密码错误
LockedException
:账户被锁定错误
3.1.1 失败Handler的处理
/**
* 登陆失败处理器,该处理器实现AuthenticationFailureHandler
* 当用户登陆成功后会自动执行该处理器里的onAuthenticationFailure方法
*/
public class LoginFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
response.setContentType("application/json;charset=utf-8");
String errMsg = "";
if (exception.getClass() == UsernameNotFoundException.class) {
errMsg = "用户名不存在";
} else if (exception.getClass() == BadCredentialsException.class) {
errMsg = "密码错误";
} else if (exception.getClass() == LockedException.class) {
errMsg = "账户被冻结";
}
System.out.println("ssssssssssssssssss");
System.out.println(errMsg);
//401:认证未通过
response.getWriter().println(JSONObject.toJSONString(Result.fail(401, errMsg)));
}
}
3.1.2 开启UsernameNotFoundException
异常
默认该异常在
AbstractUserDetailsAuthenticationProvider
被关闭,该类有个hideUserNotFoundExceptions
属性,默认为true:表示该异常关闭注:
DaoAuthenticationProvider
为AbstractUserDetailsAuthenticationProvider
的子类的子类
- 修改配置类的认证器方法
/*
* 注入认证处理器
* @param builder
* @throws Exception
*/
@Autowired
public void registerProvider(AuthenticationManagerBuilder builder) throws Exception{
//创建认证处理器对象
DaoAuthenticationProvider daoAuthenticationProvider =new DaoAuthenticationProvider();
//开启该异常
daoAuthenticationProvider.setHideUserNotFoundExceptions(false);
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
builder.authenticationProvider(daoAuthenticationProvider);//将该认证处理器交给SpringSecurity
//如上配置后下面设置无效
/*builder.userDetailsService(userDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());*/
}
3.2 退出账户的处理
3.2.1 配置类加入退出配置
.and()
.logout()//退出配置
.logoutUrl("/exit")//退出地址
.invalidateHttpSession(true)//退出销毁session
.logoutSuccessHandler(new LogoutSuccessHandlerImpl())//退出成功的处理器
3.2.2 退出成功Handler的处理
/**
* 退出成功处理器,该处理器实现LogoutSuccessHandler
* 当用户登陆成功后会自动执行该处理器里的onLogoutSuccess方法
*/
public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
response.setContentType("application/json;charset=utf-8");
response.getWriter().println(JSONObject.toJSONString(Result.success("退出成功!!!")));
}
}
3.2.3 客户端的处理
- 下拉列表添加事件
<el-dropdown @command="handleCommand">
<el-button type="warning" icon="el-icon-user">
{{curUserInfo.user_name}}
<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="1">个人中心</el-dropdown-item>
<el-dropdown-item command="2">查看订单</el-dropdown-item>
<el-dropdown-item command="3">退出</el-dropdown-item>
</el-dropdown-menu>
- 对应事件的处理,以及对后端发出退出请求
handleCommand(command) {
switch(command){
case "1":
alert("个人中心");
break;
case "2":
alert("查看订单");
break;
case "3":
this.$axios
.delete("/exit")
.then(response=>{
let result =response.data;
if(result.success){
//删除sessionStorage
window.sessionStorage.removeItem("curUserInfo");
//重置curUser
this.curUserInfo=null;
this.$notify.error({
title: result.message,
message: '退出成功',
duration: 300,
});
}
})
.catch(error=>{
alert(error)
})
break;
}
}
4 处理未登录的访问
4.1 使用axios请求拦截器处理未登录的访问
4.1.1 axios请求拦截器
- axios提供了请求拦截器,将要拦截请求在前端直接拦截,不访问后端
- 响应拦截器,将后端的响应拦截,不访问前端
- 也就是在请求或响应被
then
或catch
处理前拦截他们
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
- 如果你想在稍后移除拦截器,可以这样:
var myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);
- 可以为自定义 axios 实例添加拦截器
var instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});
axios取消请求
- 请求本身不可取消,axios内部做法本身为让请求出错,让请求回到本身
catch
内 - 本次使用 使用同一个
cancel token
取消多个请求
4.1.2 在main.js配置全局拦截器
/**
*添加请求拦截器
* connfig:是一个请求设置对象,包含请求信息
* 实现功能:客户端向服务端发送请求,通过拦截器请求并检测用户是否已登陆,如果已登陆继续访问该请求
* 若未登陆,跳转到登陆界面
*/
Vue.prototype.$axios.interceptors.request.use(function (config) {
//检测axios请求路径是否为受限路径
//在sessionStorage获取当前登陆者信息
//获得请求访问路径
let url = config.url;
//定义匹配放行路径url正则
let regUrl = /^book\/|^login$|^register$/;
//处理受限路径
if (!regUrl.test(url)) {
let curUserInfoStr = window.sessionStorage.getItem("curUserInfo");
if (curUserInfoStr == "" || curUserInfoStr == null) {//用户未登陆
let cancel;
//取消原有请求
//向config对象中添加一个cancelToken(取消令牌属性)
config.cancelToken = new axios.CancelToken((c) => {
//参数c为一个取消请求的函数
cancel = c;
});
//判断cancel是否为一个函数,若果是,他必定是一个取消请求的函数
if (typeof cancel == "function") {
cancel("请求已取消");
}
Swal.fire({
icon: 'error',
title: "请登录后访问",
showConfirmButton: false,
timer: 1000,
didClose: () => {
router.push("/login");
}
});
//跳转到登录页
}
}
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
4.2 禁用按钮处理未登录的访问
使用disabled
属性进行设置
<el-button type="warning" icon="el-icon-shopping-cart-full" style="margin-left:3px" @click="addCar" :disabled="curUserInfo==null">加入购物车</el-button>
5 用户注册功能实现
5.1 客户端
5.1.1 注册页面UI及进行路由配置
- 注册页面UI
<template>
<div class="win-reg">
<div class="register-container">
<h2>用户注册</h2>
<div class="register-form">
<el-form ref="form" :model="user" label-width="80px">
<el-form-item label="用户名">
<el-input v-model="user.user_name" placeholder="请输入用户名"></el-input>
</el-form-item>
<el-form-item label="密 码">
<el-input placeholder="请输入密码" v-model="user.user_password" show-password></el-input>
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="user.user_sex" size="medium">
<el-radio-button label="1">男</el-radio-button>
<el-radio-button label="0">女</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="爱好">
<el-checkbox-group v-model="user_hobbys_arr" size="medium">
<el-checkbox-button v-for="hobby in hobbys" :label="hobby"
:key="hobby">{{ hobby }}</el-checkbox-button>
</el-checkbox-group>
</el-form-item>
<el-form-item label="出生日期">
<el-date-picker v-model="user.user_birthday" type="date" placeholder="选择日期"
value-format="yyyy-MM-dd">
</el-date-picker>
</el-form-item>
<el-form-item label="E-mail">
<el-input v-model="user.user_email" placeholder="请输入E-mail"></el-input>
</el-form-item>
<el-form-item label="地址">
<el-input v-model="user.user_address" placeholder="请输入地址"></el-input>
</el-form-item>
</el-form>
</div>
<div>
<el-button type="primary" style="width:100%;margin-bottom:10px;height:50px" @click="register">注册</el-button>
</div>
</div>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
.win-reg {
position: absolute;
top: 0px;
bottom: 0px;
margin: 0px;
left: 0px;
right: 0px;
padding: 0px;
display: flex;
background-color: #dddddd;
/*设置弹性布局*/
flex-direction: row;
/*设置水平方向*/
justify-content: center;
/*根据direction的方向设置居中*/
align-items: center;
/*根据direction的反方向设置居中*/
}
.register-container {
margin: 30px auto;
width: 500px;
border: 0px solid red;
border-radius: 10px;
background-color: ghostwhite;
box-shadow: 0px 0px 10px 5px gray;
padding: 5px;
}
.register-container h2 {
text-align: center;
}
.register-form {
padding-right: 50px;
}
</style>
- 路由配置
import Register from "../views/Register.vue"
const routes = [
{
path: "/register",
name: "register",
component: Register,
},
];
5.1.2 向后端传递数据及做出相应处理
export default {
data() {
return {
user: {},
user_hobbys_arr: [],//绑定复选框的数组
hobbys: ["篮球", "足球", "听音乐", "网游"]
}
},
methods: {
/**
* 注册函数
*/
register() {
//将ser_hobbys_arr数组中的元素转换为字符串,再将字符串存到user.user_hobbys中
if (this.user_hobbys_arr.length != 0) {
let user_hobbys = "";
for (let hobby of this.user_hobbys_arr) {
user_hobbys = user_hobbys + "_" + hobby;
}
this.user.user_hobbys = user_hobbys.substring(1);
}
this.$axios
.post('register', this.user)
.then(response => {
let result = response.data;
if (result.success) {
this.$swal.fire({
icon: 'success',
title: result.message,
showConfirmButton: false,
timer: 1000,//延迟关闭的时间
didClose: () => {//弹窗关闭后要执行的函数
this.$router.push("/");
}
})
} else {
this.$swal.fire({
icon: 'error',
title: result.message,
showConfirmButton: false,
timer: 1000//延迟关闭的时间
})
}
})
.catch(err => {
console.log(err);
})
}
}
}
5.2 服务端
5.2.1 配置类放行路径,RegisterController的编写
- 配置类
.antMatchers("/book/*","/register")
.permitAll()//无需认证直接访问
- RegisterController
@RestController
public class RegisterController {
@Resource
private UserService userService;
@RequestMapping("/register")
public Result register(@RequestBody UserInfo userInfo){
try {
userService.register(userInfo);
return Result.success("注册成功");
} catch (Exception e) {
e.printStackTrace();
return Result.fail(500,"注册失败");
}
}
}
5.2.2 Servcie层的编写
- UserService接口
public interface UserService {
public void register( UserInfo userInfo) throws Exception;
}
- UserServiceImpl
@Service
public class UserServiceImp implements UserService {
@Resource
private UserMapper userMapper;
@Override
public void register(UserInfo userInfo) throws Exception{
//对密码进行加密
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
String encode = bCryptPasswordEncoder.encode(userInfo.getUser_password());
userInfo.setUser_password(encode);
userMapper.register(userInfo);
}
}
5.2.3 Mapper层的编写
- UserMapper
@Insert("insert into myshopping.tbl_user values (default,#{user_name},#{user_password},#{user_email},#{user_birthday},#{user_hobbys},#{user_sex},#{user_address},0)")
void register(UserInfo userInfo);