Cookie,作为 Web 应用中常用的会话管理工具,提供了一种简单而有效的方式来控制接口访问权限。本文将首先介绍 Cookie 的基本概念和工作原理,然后介绍如何利用 Cookie 来控制接口的访问权限。
1、Cookie的基本概念
Cookie 是服务器发送到用户浏览器的一小块数据,它可以在随后的请求中被浏览器发送回服务器。这种机制使得服务器能够识别和跟踪用户的状态和行为。Cookie 可以设置过期时间,从而在一定时间内保持用户的状态信息,无需在每个请求中重复提交登录凭证。
2、利用 Cookie 控制接口访问权限
通过在用户登录后设置特定的 Cookie,开发者可以控制用户对接口的访问权限。例如,可以创建一个包含用户角色或权限信息的 Cookie,服务器在处理请求时会检查这个 Cookie,以决定是否允许访问特定的接口。这种方法的优点在于实现简单,且易于与现有的 Web 应用集成。然而,它也存在一些潜在的安全风险,如 Cookie 被截获或篡改等。
开发时可以采取一些措施来保护 Cookie,例如通过设置 HttpOnly
属性防止 JavaScript 访问 Cookie,使用 Secure
属性确保 Cookie 仅通过 HTTPS 传输,以及通过 SameSite
属性限制跨站请求的 Cookie 发送。此外,合理设置 Cookie 的过期时间和限制 Cookie 的作用域也是保障安全的重要手段。
3、实践案例
1)创建后端服务
我们使用express创建一个后端服务,然后编写登录接口、模拟获取数据接口和登出接口。新建一个文件cookietest.js,代码如下,使用命令node cookietest.js运行服务。
// cookietest.js
const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();
const path = require('path');
app.use(cookieParser());
app.use(express.json());
// 创建静态服务,cookiedist中存放前端页面代码
const serveStatic = require('serve-static');
const rootPath = path.join(__dirname, 'cookiedist');
app.use(serveStatic(rootPath));
app.all('*', function (res, req, next) {
req.header('Access-Control-Allow-Origin', '*');
req.header('Access-Control-Allow-Headers', 'Content-Type');
req.header('Access-Control-Allow-Methods', '*');
req.header('Content-Type', 'application/json;charset=utf-8');
next();
});
// 登录路由
app.post('/login', (req, res) => {
const { username, password } = req.body;
// 验证用户凭据
if (username === 'user' && password === 'pass') {
// 创建会话
const sessionId = 'abc123'; // 实际应用中应该是服务器生成的值
res.cookie('sessionid', sessionId, { httpOnly: true, secure: true, sameSite: 'strict' });
res.send('Logged in');
} else {
res.status(401).send('Unauthorized');
}
});
// 受保护的接口
app.get('/protected', (req, res) => {
const sessionId = req.cookies['sessionid'];
// 验证会话标识符
if (sessionId === 'abc123') { // 实际应用中应该是具体的验证逻辑
res.send('Protected data');
} else {
res.status(401).send('Unauthorized');
}
});
// 登出路由
app.get('/logout', (req, res) => {
res.clearCookie('sessionid');
res.send('Logged out');
});
app.listen(3000, () => console.log('App running on port 3000'));
2)html页面
如代码所示,我们把cookiedist文件夹作为静态资源文件夹,所以把index.html页面放在目录cookiedist中,在html文件中编写一个简单的登录功能,并调用获取数据接口,验证是否能够正常访问。代码如下:
// cookiedist/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
用户名:<input type="text" id="username">
密码:<input type="text" id="password">
<button class="btn1">登录</button>
<button class="btn2">调用接口</button>
<button class="btn3">登出</button>
</body>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script type="module">
let btn = document.querySelector('.btn1');
btn.onclick = function(){
let username = document.querySelector('#username').value;
let password = document.querySelector('#password').value;
let body = {username,password}
console.log('body', body)
axios.post('http://localhost:3000/login',body).then(res=>{
console.log('res', res)
})
}
let btn2 = document.querySelector('.btn2');
btn2.onclick = function(){
axios.get('http://localhost:3000/protected').then(res=>{
console.log('res', res)
})
}
let btn3 = document.querySelector('.btn3');
btn3.onclick = function(){
axios.get('http://localhost:3000/logout').then(res=>{
console.log('res', res)
})
}
</script>
</html>
3)启动服务
输入启动命令:node cookietest.js,将服务启动起来,一般启动在3000端口,在浏览器中访问http://localhost:3000/index.html。
输入用户名密码点击登录,调用接口验证成功。
点击调用接口,也能正常返回数据。
然后点击登出后,再点击调用接口,此时接口就会报错:401。