1.nodejs中使用redis
const redis = require('redis')
// 创建客户端
const redisClient = redis.createClient(6379, '127.0.0.1')
redisClient.on('error', err => {
console.error(err)
})
// 测试
redisClient.set('myname', 'zhangsan2', redis.print)
redisClient.get('myname', (err, val) => {
if (err) {
console.error(err)
return
}
console.log('val ', val)
// 退出
redisClient.quit()
})
2.Nodejs中封装redis以及整体使用
conf/db.js
const env = process.env.NODE_ENV // 环境参数
// 配置
let MYSQL_CONF
let REDIS_CONF
if (env === 'dev') {
// mysql
MYSQL_CONF = {
host: 'localhost',
user: 'root',
password: 'Mysql_2018',
port: '3306',
database: 'myblog'
}
// redis
REDIS_CONF = {
port: 6379,
host: '127.0.0.1'
}
}
db/redis.js
const redis = require('redis')
const { REDIS_CONF } = require('../conf/db.js')
// 创建客户端
const redisClient = redis.createClient(REDIS_CONF.port, REDIS_CONF.host)
redisClient.on('error', err => {
console.error(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
}
app.js
const { get, set } = require('./src/db/redis')
// 解析 session (使用 redis)
let needSetCookie = false
let userId = req.cookie.userid
if (!userId) {
needSetCookie = true
userId = `${Date.now()}_${Math.random()}`
// 初始化 redis 中的 session 值
set(userId, {})
}
// 获取 session
req.sessionId = userId
get(req.sessionId).then(sessionData => {
if (sessionData == null) {
// 初始化 redis 中的 session 值
set(req.sessionId, {})
// 设置 session
req.session = {}
} else {
// 设置 session
req.session = sessionData
}
// console.log('req.session ', req.session)
// 处理 post data
return getPostData(req)
})
.then(postData => {
req.body = postData
// 处理 blog 路由
// const blogData = handleBlogRouter(req, res)
// if (blogData) {
// res.end(
// JSON.stringify(blogData)
// )
// return
// }
const blogResult = handleBlogRouter(req, res)
if (blogResult) {
blogResult.then(blogData => {
if (needSetCookie) {
res.setHeader('Set-Cookie', `userid=${userId}; path=/; httpOnly; expires=${getCookieExpires()}`)
}
res.end(
JSON.stringify(blogData)
)
})
return
}
// 处理 user 路由
// const userData = handleUserRouter(req, res)
// if (userData) {
// res.end(
// JSON.stringify(userData)
// )
// return
// }
const userResult = handleUserRouter(req, res)
if (userResult) {
userResult.then(userData => {
if (needSetCookie) {
res.setHeader('Set-Cookie', `userid=${userId}; path=/; httpOnly; expires=${getCookieExpires()}`)
}
res.end(
JSON.stringify(userData)
)
})
return
}
// 未命中路由,返回 404
res.writeHead(404, {"Content-type": "text/plain"})
res.write("404 Not Found\n")
res.end()
})
router/user.js
const { login } = require('../controller/user')
const { SuccessModel, ErrorModel } = require('../model/resModel')
const { set } = require('../db/redis')
const handleUserRouter = (req, res) => {
const method = req.method // GET POST
// 登录
if (method === 'POST' && req.path === '/api/user/login') {
const { username, password } = req.body
// const { username, password } = req.query
const result = login(username, password)
return result.then(data => {
if (data.username) {
// 设置 session
req.session.username = data.username
req.session.realname = data.realname
// 同步到 redis
set(req.sessionId, req.session)
return new SuccessModel()
}
return new ErrorModel('登录失败')
})
}
// 登录验证的测试
if (method === 'GET' && req.path === '/api/user/login-test') {
if (req.session.username) {
return Promise.resolve(
new SuccessModel({
session: req.session
})
)
}
return Promise.resolve(
new ErrorModel('尚未登录')
)
}
}
module.exports = handleUserRouter
3.正向代理和反向代理
nginx介绍:
1.高性能的web服务器,开源免费
2.一般用于做静态服务、负载均衡(本课用不到)
3.还有反向代理(本课用到)
正向代理:
前向代理作为客户端的代理,将从互联网上获取的资源返回给一个或多个的客户端,服务端(如Web服务器)只知道代理的IP地址而不知道客户端的IP地址;
所谓反向代理:
服务器根据客户端的请求,从其关联的一组或多组后端服务器(如Web服务器)上获取资源,然后再将这些资源返回给客户端,客户端只会得知反向代理的IP地址,而不知道在代理服务器后面的服务器簇的存在。
访问localhost/index.html是8080端口,经过nginx反向代理,遇见/…形式代理到8081端口,遇见/api/…代理到nodejs后端服务器。浏览器只知道代理的IP地址,不知道后端html静态文件和nodejs后端服务器的存在。
Nginx系列文章:https://blog.csdn.net/Milogenius/column/info/20827
1. 启动
start nginx / nginx.exe
2. 停止
nginx -s stop 快速停止nginx,可能并不保存相关信息
nginx -s quit 完整有序的停止nginx,并保存相关信息
3. 重启
nginx -s reload 优雅重启,并重新载入配置文件nginx.conf
4. nginx -s reopen
重新打开日志文件,一般用于切割日志
5. nginx -v 查看版本
6.nginx -t 检查nginx的配置文件
7.nginx -V 详细版本信息,包括编译参数
8.nginx -c filename 指定配置文件
主要配置:
server {
listen 80; //nginx默认80端口
server_name 你的域名;
location / {
proxy_pass 本地ip+端口号;
}
}
//一个实例
http{
server{
listen 8800;
server_name localhost;
location / {
proxy_pass http://localhost:8000;
}
location /api/ {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
}
}
}
proxy_pass可以参考:https://blog.csdn.net/ainuser/article/details/80260144
proxy_set_header可以参考:
https://blog.csdn.net/felix_yujing/article/details/51682655
https://www.cnblogs.com/jsonhc/p/7199295.html?utm_source=itdadao&utm_medium=referral#top
前端联调界面
cnpm install http-server -g
http-server -p 8001
然后就可以输入localhost:8001/xxx.html进行访问了
url拼接参数格式
可以参考:https://www.cnblogs.com/yanggb/p/11143489.html
4.用户名密码加密
utils/cryp.js
const crypto = require('crypto')
// 密匙
const SECRET_KEY = 'WJiol_8776#'
// md5 加密
function md5(content) {
let md5 = crypto.createHash('md5')
return md5.update(content).digest('hex')
}
// 加密函数
function genPassword(password) {
const str = `password=${password}&key=${SECRET_KEY}`
return md5(str)
}
module.exports = {
genPassword
}
5.原生Node博客知识点总结
server和前端的区别:
6.Express初始化环境
关于登陆:
1.使用express-session和connect-redis管理,简单方便
2.req.session保存登录信息,
3.登陆校验loginCheck做成express中间件 ,因为一些操作要验证是否已经登陆
关于Express中使用cookie、session和redis参考文章:
https://segmentfault.com/a/1190000013048314#articleHeader0
https://andrewpqc.github.io/2017/09/17/cookie-and-session-in-Express-use-redis-to-make-it-work-better/
http://kirochen.com/2015/07/09/about-cookie-session/
https://techblog.toutiao.com/2017/11/29/nodezhong-sessionchi-jiu-hua-yu-redishuan-cun/
https://juejin.im/post/5a27a867f265da432652b618
现在来看具体代码:
//app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const session = require('express-session')
const RedisStore = require('connect-redis')(session)
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
const blogRouter = require('./routes/blog');
const userRouter = require('./routes/user')
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
const redisClient = require('./db/redis')
const sessionStore = new RedisStore({
client: redisClient
})
app.use(session({
secret: 'WJiol#23123_',
cookie: {
// path: '/', // 默认配置,不写也可以
// httpOnly: true, // 默认配置
maxAge: 24 * 60 * 60 * 1000
},
store: sessionStore
}))
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/api/blog', blogRouter);
app.use('/api/user', userRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
//routes/user.js
router.post('/login', function(req, res, next) {
const { username, password } = req.body
const result = login(username, password)
return result.then(data => {
if (data.username) {
// 设置 session
req.session.username = data.username
req.session.realname = data.realname
res.json(
new SuccessModel()
)
return
}
res.json(
new ErrorModel('登录失败')
)
})
});
app.js中app.use(session)中间件作用可以理解为注册session和开辟redis空间,如果不是登陆路由,其他路由依然会创建session对象和cookie值,并在session值存储到redis中,但登陆路由执行后,对session赋值,并存储到redis中。
所以请求(不论是不是登陆)服务端都会生成session和cookie,并保存到redis中。