本篇完成新页面对网站登录的token令牌存储,员工以及顾客的用户注册,限制在本地存储localStorage中无token字段的情况下对限制资源进行访问。
注意1、本工程使用前后端不分离进行开发,后端拦截器Interceptor进行拦截时,须对静态资源进行释放。
1、创建注册以及登录页面,后端成功检验登录时浏览器向后端发送携带的信息后,向前端发送指定格式包含token的令牌,前端将获得的token存储到浏览器的本地存储(LocalStorage)以便后面进行资源(非静态资源)访问时进行携带。
当登录成功后跳转到官方主页,并且在主页中发送携带token的请求给后端,后端解析令牌中信息返回用户名名称给主页来显示用户的登录信息。
当用户再次点击名字(原登录按钮)时,网站会退出账号并且重新跳转至登录界面,并且删除LocalStorage中存储的token。
登录完成之后用户访问限制资源时将携带token对后端进行访问,并且前端进行后端发送资源请求之前会对浏览器当前LocalStorage当中是否有token属性进行检验,如无token字段(没登录或用户删除token字段)页面会跳转至登录界面进行重新登录。
而当用户对令牌进行修改,其会在后端的处理中发现错误,并返回指定对象,以此提示用户“账号出现错误请重新登录”。
(为跟好呈现过程效果,没有直接进行跳转)
前端在访问后端限制资源时须携带正确token令牌,格式由前端JS自行定义如此处将token存储于Authorization进行封装,然后交由后端Interceptor进行获取与验证
以下为一些前端操作的具体JS实现:
1、登录页面成功登录后将token存储于LocalStorage
// 发送数据到后端服务器
customFetch('/login', {
method: 'POST', // 使用 POST 方法
headers: {
'Content-Type': 'application/json'
},
credentials: 'include', // 如果需要携带 cookie
body: JSON.stringify({ // 通过 body 传递 JSON 数据
username: username,
password: password,
role: role.value
})
})
.then(response => response.json())
.then(data => {
if (data.code === 200) {
// 登录成功,存储 token
localStorage.setItem('token', data.data.token);
// 跳转到 official.html 页面,不携带 username 参数
window.location.href = 'official.html';
} else {
// 登录失败,显示错误信息
document.getElementById('error').textContent = '用户名或密码错误';
}
})
.catch(error => {
console.error('Error:', error);
document.getElementById('error').textContent = '登录失败,请重试';
});
2、重新点击原登录按钮时退出原账号(删除原来存储的token)
// 为登录按钮添加点击事件监听器
loginButton.addEventListener('click', function() {
if (username) {
// 如果已经登录,可以添加登出功能或其他操作
alert(`用户 ${username} 已登录`);
// 清除token
localStorage.removeItem('token');
// 重定向到登录页面
window.location.href = 'login.html';
} else {
// 如果没有登录,跳转到 login.html 页面
window.location.href = 'login.html';
}
});
3、使用钩子函数,在访问限制资源时,页面于发送后端请求前检验浏览器LocalStorage是否存储token令牌。
// 钩子函数
mounted() {
// 检查 token 是否存在
const token = localStorage.getItem('token');
if (!token) {
alert('请先登录');
window.location.href = 'login.html'; // 重定向到登录页面
return;
}
// 页面加载完成之后,发送ajax请求,获取数据
this.search();
}
}).mount('#container')