登录逻辑,前后端完整实现:
1,用户名,密码验证成功后,后端签发token返回给前端
2,前端把token保存到本地存储
补充:
http是无状态的,意思是说你这次访问了服务器,关闭网页,再次访问服务器,服务器是没有意识到又是你来访问的
login() {
this.$api.users
.login(this.user)
.then(({ data }) => {
const { accessToken } = data
localStorage.setItem('token', accessToken)
this.$router.push('/products/create')
})
.catch((err) => {
this.$message.error(err.response.data.message)
})
},
注:
如果token不保存,则如果知道其他非登录页的路由地址可以直接跳过登录页,登录页就没有起到真正的作用。
仅仅判断本地有没有token不行 因为可以在浏览器调试模式下自己填入token,所以在请求时需要带上token 信息发送给后端验证
3,每次请求前,通过axios请求拦截器,统一发送token
请求拦截器 axios intercept config就是axios.create({})括号里的对象
request.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token')
if (token) config.headers.Authorization = `Bearer ${token}`;
return config
},
(error) => Promise.reject(error),
)
4,通过Vue导航守卫,和axios响应拦截器,统一保护页面
导航守卫 全局前置守卫 判断本地是否有token
router.beforeEach((to, from, next) => {
const token = localStorage.getItem('token')
if (to.name !== 'Login' && !token) next({ name: 'Login' })
else next()
})
响应拦截器
是在请求拿到数据之后,在.then .catch之前 。 用于处理后端检验token的结果,如果状态码为401 则跳回登录页 弹出错误信息message
需要注意的是 在js中使用elementui的message组件不能写成this.$message
request.interceptors.response.use(
(response) => response,
({ response }) => {
const { status, data } = response
const { message } = data
Message.error(message)
if (status === 401) router.push({ name: 'Login' })
return Promise.reject(error)
},
)
http请求码 200 201 成功 204 无内容 通常用于删除接口
301 永久重定向 用于域名网址需要更改时,老的域名已经被百度收录,所以更改需要重定向并通知百度 304 临时重定向
400 接口传参 请求参数的格式错误 接口传参最少有四个地方可以: 路径参数 查询参数 请求头参数 请求体参数
401 后端校验token失败,前端直接跳到登录页,代表未登录 获得token过期了或者没传 或者传错了
403 代表无权限,登录了权限过低,某些接口不能调用
404 请求资源找不到 请求地址写错了,需要检查请求路径是否敲错了或者是否请求方法错误 get写成了post
500 通常是后端代码写错了 502 服务器配置错误 503 服务器超载了
翻译为请求报文为:
登录页面的优化:
优化一:用户名和密码输入之后敲回车 可以请求接口
@keyup.enter.native = ''
native是绑定keyup事件在组件的最外层的div上 组件本身没有keyup事件
优化二:用户名和密码都填完之后button才能点击,只填一个或者不填是不能点击的
<el-button
type="primary"
@click="login"
:disabled="!canSubmit"
>
登录
</el-button>
computed: {
canSubmit() {
const { username, password } = this.user
return Boolean(username && password)
},
},
优化三:输入框小到一定程度不能再小了,不影响输入
优化四:变小的过程中 表单不那么居中了,是因为每一个form-item都有margin-bottom 需要设置最后一个form-item的margin-bottom为0
.el-form-item:last-child {
margin-bottom: 0;
}
其他:
本地存储是和域名相关的 保证origin域一样都能拿到 不可能京东的token会拿到qq的token jd.com token = 111 qq.com token = 222
哪些路由需要登录?
可以在route中添加meta属性 里面可以随便保存信息 定义的只是一个标记
meta: { authRequired: true },