在上一章节中, 我们已经学习了koa-router这个中间件, 那么这一章节, 我们将继续学习如何来使用koa-router, 如下:
使用 koa-router 定义路由
const Koa = require('koa');
const bodyparser = require('koa-bodyparser');
const app = new Koa();
const Router = require('koa-router');
const router = new Router();
// 注册中间件
app.use(bodyparser());
router.get('/', (ctx, next) => {
const { response } = ctx;
response.body = 'index page';
});
// 查
router.get('/home', async (ctx, next) => {
const { response } = ctx;
response.body = 'home page';
await next();
});
// 提交
router.post('/list', (ctx, next) => {
const { response } = ctx;
response.body = {
list: []
};
});
// 更改
router.put('/list', (ctx, next) => {
const { response } = ctx;
response.body = {
list: []
};
});
// 删除
router.delete('/list', (ctx, next) => {
const { response } = ctx;
response.body = {
list: []
};
});
app.use(router.routes());
app.use(router.allowedMethods()); // 路由的异常处理
app.listen(3000, () => {
console.log(`http://127.0.0.1:3000`);
});
通过上一章节我们介绍了koa-router的多个中间件机制, 和当前章节里面的koa-router的常用方法, 下面我将使用jsonwebtoken来实现token验证
使用 jsonwebtoken 来实现登录验证
const Koa = require('koa');
const bodyparser = require('koa-bodyparser');
// sign 用来生成token
// verify 用来解析token
const { sign, verify } = require('jsonwebtoken');
// 私钥
const PRIVATE_KEY = 'montage_fz';
const app = new Koa();
const Router = require('koa-router');
const router = new Router();
// 注册中间件
app.use(bodyparser());
// 注册页面
router.get('/', (ctx, next) => {
const { response } = ctx;
response.body = `
<h1>注册</h1>
<form action="/register" method="post">
<div>用户名: <input type='text' name='username'></div>
<div>密 码: <input type='text' name='password'></div>
<button type="submit">提交</button>
</form>
`;
});
// 注册
router.post('/register', async (ctx, next) => {
const { request, response } = ctx;
const { body } = request;
try {
const { username, password } = body;
if (username && password) {
// 过期时间为六十秒, 每次注册的时候, 会生成一个新的token, 在实际项目中, 是在每次登陆的时候, 生成一个新的token
const token = sign({ username, password }, PRIVATE_KEY, {
expiresIn: 60
});
response.body = {
message: '注册成功',
username,
token
};
} else {
response.body = '用户名和密码不能为空';
}
} catch (e) {
response.body = e;
}
});
// 将token的验证, 单独封装, 方便多地方调用
const verity = async (ctx, next) => {
const { request, response } = ctx;
const { query } = request;
try {
const { token, username, password } = query;
if (token) {
// 解析token
const decodeToken = verify(token, PRIVATE_KEY);
const { username: user, password: pass } = decodeToken;
if (username === user && password === pass) {
await next();
} else {
ctx.redirect('/');
}
} else {
response.body = '请携带token';
}
} catch (e) {
response.body = e;
}
};
// 登录
router.get('/login', verity, async (ctx, next) => {
const { request, response } = ctx;
response.body = '登录成功';
});
app.use(router.routes());
app.use(router.allowedMethods()); // 路由的异常处理
app.listen(3000, () => {
console.log(`http://127.0.0.1:3000`);
});
问题 : 为什么要使用 token?
在使用token之前, 我们都是采用cookie和session来进行验证, 验证的过程主要分为以下几个步骤:
1.服务端session是用户第一次访问应用时,服务器就会创建的对象,代表用户的一次会话过程,可以用来存放数据。服务器为每一个session都分配一个唯一的sessionId,以保证每个用户都有一个不同的session对象。
2.服务器在创建完session后,会把sessionId通过cookie返回给用户所在的浏览器,这样当用户第二次及以后向服务器发送请求的时候,就会通过cookie把sessionId传回给服务器,以便服务器能够根据sessionId找到与该用户对应的session对象。
token验证过程:
1.用户在浏览器中输入用户和密码,后台服务器通过加密或者其他逻辑,生成一个Token。
2.前端获取到Token,存储到cookie或者localStorage中,在接下来的请求中,将token通过url参数或者HTTP Header头部传入到服务器
3.服务器获取token值,通过查找数据库判断当前token是否有效
从上面不难看出, session是储存在内存上的,每个用户登录都会将session储存在服务器的内存中, 而token是存在客户端, 从而减少了服务端的压力, 在加上不同的服务端上的session是不同的, 所以不能进行共享, 而token也可以解决这个问题.