自己学习记录,写的不详细,没有误导,不想误导
大概的登录逻辑,前后端完整实现:
1.用户名,密码验证成功后,后端签发token返回给前端
2.前端把token保存到本地存储
3.每次请求前,通过axios请求拦截器,统一发送token
4.通过Vue导航守卫,和axios响应拦截器,统一保护页面
新建个前端项目用来演示
这里我用的是VSCode
引入ElementUI
npm i element-ui -S
并且在main.js中引入
因为需要向后端发送请求,这里用axios
npm install axios
先整个登录页面演示,在views下创建login.vue
注意下,安装好axios,局部使用的时候
引入
然后,如果,就可以发送请求。可以全局进行封装
<template>
<div>
<el-form :rules="rules" ref="loginForm" :model="loginForm" class="loginContainer">
<h3 class="loginTitle">系统登录</h3>
<el-form-item prop="username">
<!-- aoto-complete自动补全,其实可以不加,具体什么用不了解 -->
<el-input type="text" aoto-complete="false" v-model="loginForm.username" placeholder="请输入用户名"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input type="password" aoto-complete="false" v-model="loginForm.password" placeholder="请输入密码"></el-input>
</el-form-item>
<el-button type="primary" @click="submitLogin" style="width:100%">登录</el-button>
</el-form>
</div>
</template>
<script>
import axios from 'axios'
export default {
name:"login",
data(){
return{
captchaUrl:'',
loginForm:{
username:'admin',
password:'123456',
//code:''
},
checked:true,
rules:{//校验规则需要FORM表单上绑定rules,还需要在对应item上写prop才可以对应
username:[
{required: true, message:'请输入用户名', trigger: 'blur'},
{min:5,max:12,message:'长度在6到12个字符',trigger:'blur'}
],
password:[
{required: true, message:'请输入密码', trigger: 'blur'},
{min:6,max:12,message:'长度在6到12个字符',trigger:'blur'}
],
}
}
},
methods:{
submitLogin(){
this.$refs.loginForm.validate((valid) => {
if (valid) {
//alert('submit!');
axios.get("http://localhost:8081/login",{params:this.loginForm}).then(function(res){
console.log(res)
if(res.data!=null){
//window.localStorage.setItem("access-admin",JSON.stringify(res.data))//存字符串类型
//如果登录成功
window.sessionStorage.setItem("token",JSON.stringify(res.data.token))
}
})
} else {
this.$message.error('请正确输入登录信息');
return false;
}
});
}
}
}
</script>
<style>
.loginContainer{
border-radius: 15px;
background-clip: padding-box;
margin:180px auto;
width:350px;
padding:15px 35px 15px 35px;
background: #fff;
border: 1px solid #eaeaea;
box-shadow: 0 0 25px #cac6c6;
}
.loginTitle{
margin:0px auto 40px auto;
text-align:center;
}
.loginRemember{
text-align: left;
margin:0px 0px 15px 0px;
}
</style>
路由
后端SpringBoot,引入了Web JDBC MYSQL MYBATIS
简单些就不查数据库了,引入Web就可以了
创建一个实体类
登录接口,先用来演示,token现在一般主流用JWT,这里用来演示,千万别误解
前端启动默认用的8080,后端8081
这里想起来,发送Get请求,也太草率了.请求改成post,另外跨域问题,一会解决.改下,发送post请求
然后先在后端
这里主要演示到底返回的这个res是个什么
如果我后端故意报个错
把匿名函数改成箭头函数,他妈什么乱七八糟的
如果登录成功
这里我们配置一个全局的关于请求和响应的拦截器
在src下创建utils文件夹,新建api.js
// 导入安装的axios
import axios from 'axios'
// 导入elementUI错误消息提示
import { Message } from 'element-ui'
// 导入路由
import router from '../router'
// 创建axios请求实例,并暴
const myaxios = axios.create({
baseURL: 'http://localhost:8081',
timeout: 1000,
});
// 添加请求拦截器
myaxios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
// 一般是添加token再发送
let token=window.sessionStorage.getItem("token")
if(token){
config.headers['token']=token
}
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// // 添加响应拦截器
// myaxios.interceptors.response.use(function (response) {
// // 2xx 范围内的状态码都会触发该函数。
// // 对响应数据做点什么
// // 如果业务逻辑错误
// if (response.status || response.status === 200) {
// // 如果返回数据中code=500,或者是未登录401,权限错误403
// if (response.data.code === 500 || response.data.code === 401 || response.data.code === 403) {
// Message.error({ message: response.data.message });
// return;
// }
// // 如果是其他
// if (response.data.message) {
// Message.success({ message: response.data.message });
// }
// }
// return response.data;
// }, function (error) {
// // 超出 2xx 范围的状态码都会触发该函数。
// // 对响应错误做点什么
// if (error.response.data.code === 504 || error.response.data.code === 404) {
// Message.error({ message: '服务器被吃了( •̀ ω •́ )' });
// } else if (error.response.data.code === 403) {
// Message.error({ message: '权限不足,请联系管理员' });
// } else if (error.response.data.code === 401) {
// Message.error({ message: '尚未登录,请登录!' });
// //跳往登录界面
// router.push('/');
// } else {
// if (error.response.data.message) {
// Message.error({ message: error.response.data.message });
// }else{
// Message.error({ message:'未知错误去( •̀ ω •́ )✧'});
// }
// }
// return;
// });
//暴露接口
export default myaxios;
在main.js文件中全局引入配置好的myaxios。这样你在任何一个组件里都可以使用this.$axios.get()、this.$axiso.post()
等等直接向服务器发送请求。
发送axios不需要局部引入
且每次请求前,会去看,SessionStorage里有没有token
有的话放到请求头里,后端设置过滤器,验证请求头里的token
后端添加过滤器,具体逻辑就是判断Token,一般用JWT,这里写死了,不要误解
路由导航