本文记录了nodejs中通过session和token如何实现用户登录
首先使用express搭一个服务
- 这块可以看我另外一篇文章,本文注重实现登录功能express+mysql实践
express 中间件
- 中间件能干什么?连接
- 执行任何代码。
- 修改请求和响应对象。
- 终结请求-响应循环。
- 调用堆栈中的下一个中间件。
- 我们需要知道任何一个接口访问服务器的时候对应用户状态,这里需要一个统一的处理,中间件可以帮我们做这些事情
- 我们自定义一个中间件,它负责检测每一个接口请求服务器的时候对应用户状态。
路径 /middleware/auth.js
const auth = (req, res, next) => {
/**
* 这里做一些逻辑判断,可能是校验session_id或者token,下面会说到
* 校验通过正常放行或者响应数据
* 校验不通过则直接返回错误信息
* */
if (true) {
next();
} else {
res.render('fail', { message: '请先登录!' })
}
}
复制代码
- 那么我们如何使用这个中间件呢?
路径 /routers/user.js
// 引入刚才自定义好的中间件
var { auth } = require('../middleware/auth');
// 在你希望校验用户信息的接口中使用该中间件,如下:
/* 编辑用户 */
router.post('/edit', auth, userCtl.editUser);
// 不需要校验的接口则无需使用
/* 用户登录 */
router.post('/signIn', userCtl.signIn);
复制代码
- Ok,我们完成了校验用户状态的流程,现在要说一下基于session和token都如何实现呢?
session实现方法
流程
- 用户登录,用户信息校验通过后服务器会存储必要的用户信息到session或redis中,并且生成一个id,这里叫它session_id,通过session_id可以获取用户信息。
- 种cookie,设置Cookie为sessionId=xxxxxx|checksum并发送HTTP响应, 仍然为每一项Cookie都设置签名,cookie是携带在http请求中的,后续请求校验cookie中有没有对应sessionId即可判断用户登录状态。
做法
-
使用
cookie-session
第三方包npm install cookie-session
下载依赖
```js 路径 /app.js var cookieSession = require('cookie-session'); app.use(cookieSession({ name: 'session', keys: ['key1', 'key2'] })) ``` 复制代码
-
当用户登录成功的时候
路径 controllers/user.js
// 用户信息校验通过
req.session.username = name; //我这里保存了一个用户名称在cookie中
复制代码
- 如何校验?
这里就要用到我们自定义好的中间件了
路径 /middleware/auth.js
const auth = (req, res, next) => {
const userName = req.session.username;
if (userName) {
next();
} else {
res.render('fail', { message: '请先登录!' })
}
}
复制代码
token实现方法
流程
- 用户登录,用户信息校验通过后服务通过
jwt
将必要的用户信息加密,生成一串密文,这里称为token并将token返回前端。 - 后续接口请求服务器用户用
jwt
校验token是否正常来判断用户的状态。 - 使用
jsonwebtoken
第三方包npm install jsonwebtoken
下载依赖- 对称加密用法
路径 controllers/user.js // 用户信息校验通过 var token = jwt.sign({ password: password }, 'afeng666'); res.render('success', { data: JSON.stringify({ token }), message: '登录成功' }) 复制代码
- 对称加密校验
路径 /middleware/auth.js const auth = (req, res, next) => { let token = req.get('x-token'); // 捕获解密是否正常 try { var decoded = jwt.verify(token, 'afeng666'); next(); } catch (error) { res.render('fail', { message: '请先登录!' }); } } 复制代码
- 非对称加密用法(比对称加密更安全)
- 需要下载Openssl生成公钥和私钥
- 贴个下载地址
- openssl安装完成后在openssl/bin目录下执行如下命令,当然你也可以配置成全局命令。
生成公钥: openssl genrsa -out rsa_private_key.pem 1024 生成私钥: openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 复制代码
- 然后将对应两个文件放到你的文件中。
- 用户信息校验通过后使用私钥加密。
路径 controllers/user.js // 用户信息校验通过 const privateKey = fs.readFileSync(path.join(__dirname , '../rsa/rsa_private_key.pem')); //非对称加密指定加密方法 const token = jwt.sign({ password: password }, privateKey , { algorithm: 'RS256'}); res.render('success', { data: JSON.stringify({ token }), message: '登录成功' }) 复制代码
6.使用公钥解密对比
路径 /middleware/auth.js
const auth = (req, res, next) => {
let token = req.get('x-token');
const publicKey = fs.readFileSync(path.join(__dirname, '../rsa/rsa_public_key.pem'));
// 捕获解密是否正常
try {
const result = jwt.verify(token, publicKey);
next();
} catch (error) {
res.render('fail', { message: '请先登录!' });
}
}
复制代码
以上
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END