跟我一起学NodeJs之使用redis做登录验证
Redis
为了更安全完美的做登录验证,我们引入录入redis,当然,存session只是redis用法之一。
安装
看教程: https://www.runoob.com/redis/redis-install.html
NodeJS链接redis demo
我们先用一个demo来演示如何使用nodejs链接redis。
首先我们需要npm 安装redis。这里省略。
const redis = require('redis')
// 创建客户端
const redisClient = redis.createClient(6379, '127.0.0.1',)
redisClient.on('error', err => {
console.log(err)
})
//测试
redisClient.set('myname', 'zhangsan', redis.print)
redisClient.get('myname', (err, val) => {
if(err) {
console.log(err)
return
}
console.log(val)
// 退出redis
redisClient.quit()
})
和nodejs连接mysql类似,我们需要先起一个redis服务,然后对其进行对应操作即可,我们在使用的过程中,需要对其做一个封装。
我们也是需要在项目中根据环境配置
// conf/db.js
REDIS_CONF = {
port: 6379,
host: '127.0.0.1'
}
// db/redis.js
const redis = require('redis')
const { REDIS_CONF } = require('../conf/db')
// 创建客户端
const redisClient = redis.createClient(REDIS_CONF.port, REDIS_CONF.host)
redisClient.on('error', err => {
console.log(err)
})
function set(key, val) {
if (typeof val === 'object') {
val = JSON.stringify(val)
}
redisClient.set(key, val, redis.print)
}
function get(key) {
const promise = new Promise((resolve, reject) => {
redisClient.get(key, (err, val) => {
if (err) {
reject(err)
return
}
if (val === null) {
resolve(null)
return
}
try {
resolve(
JSON.parse(val)
)
} catch (ex) {
resolve(val)
}
})
})
return promise
}
module.exports = {
set,
get
}
我们对上面的demo做了优化改造,要其能适用于我们的项目,这样,我们就完成了一个封装。
在项目中完成Redis登录验证
我们需要将上面的封装工具用在项目中,重写我们之前处理session的逻辑。
const { get, set } = require('./src/db/redis')
req.sessionId = userId
get(req.sessionId).then(sessionData => {
if (sessionData === null) {
// 初始化redis中的session值
set(req.sessionId, {})
// 设置session
req.session = {}
} else {
// 设置session
req.session = sessionData
}
})
这样我们就利用我们封装的Redis方法,完成了对于session的处理。因为我们要使用session做登录验证,所以还是需要改动一下原来路由中登录的处理逻辑
req.session.username = data.username
req.session.realname = data.realname
// 同步到redis中
set(req.sessionId, req.session)
对,我们就是相对于之前,多一个将处理的session同步到redis中,这样我们在登录后,访问其他接口的时候,就可以直接从redis里面去session了。
封装登录验证中间件,为每一个需要登录访问的接口,加校验
因为登录严重是一个全局通用的功能,所以我们将其封装为一个中间价,供所有接口使用,我们的demo比较简单,所以只在blog路由中使用这个中间件
// 统一的登录验证函数
const loginCheck = req => {
if(!req.session.username) {
return Promise.resolve(new ErrorModel('没有登录'))
}
}
如上,我们只看其没有登录的情况即可,使用如下
const loginCheckResult = loginCheck(req)
if(loginCheckResult) {
// 未登录
return loginCheck
}
我们在需要登录验证的接口前面这么使用就可以了。
至此,我们的登录验证就OK了。就可以通过浏览器和后端进行联调了
和前端联调
作为前端,对联调肯定不陌生,那么我们今天将站在后端的角度去看待联调,注意两点
- 登录依赖cookie,必须使用浏览器来联调
- cookie跨域不共享,前端和server端必须同域
- 需要使用Nginx做代理,让前后端同域
于是我们就要学习一下Nignx代理配置
Nginx代理
- 高性能的web服务器,开源免费
- 一般用来做静态服务,负载均衡
- 反向代理
安装
http://nginx.org/en/download.html
常用命令
nginx -t 验证(nginx.conf)配置文件是否有语法错误
nginx -V 查看Nginx的版本号
start nginx 启动Nginx (windows下start nginx)
nginx -c /usr/local/nginx/conf/nginx.conf 启动nginx
nginx -s stop 快速停止或关闭Nginx
nginx -s quit 正常停止或关闭Nginx
nginx -s reload 配置文件修改重装载命令
nginx -h 查看帮助信息
nginx -s reopen 打开日志文件
也可以自行根据需要网上找相关答案,这里不再赘述
然后,你就可以做前后端联调了,大致思路是这样的:
- 我们配置一个Nginx监听端口
- 将监听端口不同路径代理到不同的服务上,这里指前后端服务
- 后端就是我们一直写的Nodejs服务
- 前端服务可以使用dev server(一般基于react/vue等框架)
- 也可以使用http-server启动本地的html文件
这样就可以做到同域下的联调了,试试吧!
至此。我们的接口以及联调就讲解完成了。