前后端分离使用 Token 登录解决方案
前后端分离使用 Token 登录解决方案
这篇文章写一下前后端分离下的登录解决方案,目前大多数都采用请求头携带 Token 的形式。 开写之前先捋一下整理思路:
首次登录时,后端服务器判断用户账号密码正确之后,根据用户id、用户名、定义好的秘钥、过期时间生成 token ,返回给前端;
前端拿到后端返回的 token ,存储在 localStroage 和 Vuex 里;
前端每次路由跳转,判断 localStroage 有无 token ,没有则跳转到登录页,有则请求获取用户信息,改变登录状态;
每次请求接口,在 Axios 请求头里携带 token;
后端接口判断请求头有无 token,没有或者 token 过期,返回401;
前端得到 401 状态码,重定向到登录页面。
我这里前端使用 Vue ,地址:vue-token-login
后端使用阿里的 egg,地址:egg-token-login
首先,我们先轻微封装一下 Axios:
把 Token 存在localStroage,检查有无 Token ,每次请求在 Axios 请求头上进行携带,封装request.js组件,
//引入axios
import axios from "axios";
//axios.create可以帮助我们创建一个实力对象(其实他所创建的这个实力对象就是axios对象)
//创建实例
const request = axios.create({
// baseURL : "/dev-api",
baseURL : process.env.VUE_APP_BASE_API,
timeout : 5000, //请求超时时间
});
//添加拦截器
//请求拦截
request.interceptors.request.use(config=>{
// 在发送请求之前做些什么
return config;
},error=>{
// 对请求错误做些什么
return Promise.reject(error);
})
//响应拦截
request.interceptors.response.use(response=>{
// 在响应成功之前做些什么
return response;
},error=>{
// 对响应失败做些什么
return Promise.reject(error);
})
//导出request对象
export default request;
复制代码
然后是接口单独在封装一个接口,
import request from "../utils/request"
export default {
//登录接口
login(mobile,password){
return request({
url : "/user/login",
method : "post",
data : {
mobile,
password,
}
})
},
//获取用户信息接口
getInfo(token){
return request({
method : "get",
url : `/user/info/${token}`,
})
}
}
复制代码
定义路由
const router = new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'Index',
component: Index,
meta: {
requiresAuth: true
}
},
{
path: '/login',
name: 'Login',
component: Login
}
]
上面我给首页路由加了 requiresAuth,所以使用路由钩子来拦截导航,localStroage 里有 Token ,就调用获取 userInfo 的方法,并继续执行,如果没有 Token ,调用退出登录的方法,重定向到登录页。})
复制代码
Vuex
首先,在 mutation_types 里定义:
然后在 mutation 里使用它们:
在之前封装 Axios 的 JS里定义请求接口:
在 Vuex 的 actions 里引入:
定义 action
总结
访问登录注册之外的路由,都需要登录权限,比如首页,判断有无token,有则访问成功,没有则跳转到登录页面;
成功登录之后,跳转到之前重定向过来的页面;
token 过期后,请求接口时,身份过期,跳转到登录页,继续第二步;这一步主要用了可以做7天自动登录等功能。