- 动态服务器
- 实现用户注册功能
- 实现用户注册功能
- 实现用户登录功能
- Cookie介绍
- 把cookie替换成user id
- 使用session保存用户信息
-曾老湿, 江湖人称曾老大。
-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。
动态服务器
静态服务器 VS 动态服务器 |
---|
我们也可以说,静态网页和动态网页,还有静态请求,动态请求。
判断依据: 是否请求了数据库,没有请求数据库,就是静态服务器,请求了数据库就是动态服务器
但是数据库和前端没有啥关系,所以我们使用json文件模拟数据库。
首先,我们先创建一个项目,把上次的static-server复制一下即可。

使用vscode打开。

创建一个目录,db当数据库,里面创建一个user.json文件,当做是数据库中的表,然后往里写数据
代码语言:javascript复制[
{"id":1,"name":"zls","password":"123"},
{"id":2,"name":"haoda","password":"124"},
{"id":3,"name":"qls","password":"125"}
]

测试读取数据。
代码语言:javascript复制const fs = require('fs')
// 读数据库
const userString = fs.readFileSync('./db/user.json').toString()
// 获取到的数据,必须要转换成数组
const userArray = JSON.parse(userString)
// 打印出两种数据.是不一样的,看起来差不多,其实差很多
console.log(userString)
console.log(userArray)

测试写数据库
代码语言:javascript复制const user4 = {id:4,name:'drz',password:'126'}
userArray.push(user4)
const string = JSON.stringify(userArray)
fs.writeFileSync('./db/user.json',string)

这样就写进去了,所以格式略微有点变化。不过问题不大。
实现用户注册功能
创建一个注册页面
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
<title>注册</title>
</head>
<body>
<form action="">
<div>
<label>用户名<input type="text" name="name"></label>
</div>
<div>
<label>密码<input type="password" name="password"></label>
</div>
<div>
<button type="submit">注册</button>
</div>
</form>
</body>
</html>

引入jQuery

代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
<title>注册</title>
</head>
<body>
<form id="registerForm">
<div>
<label>用户名<input type="text" name="name"></label>
</div>
<div>
<label>密码<input type="password" name="password"></label>
</div>
<div>
<button type="submit">注册</button>
</div>
</form>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.0/jquery.min.js"></script>
<script>
const $form = $('#registerForm')
$form.on('submit',(e)=>{
e.preventDefault()
const name = $form.find('input[name=name]').val()
const password = $form.find('input[name=password]').val()
console.log(name)
console.log(password)
$.ajax({
method:'POST',
url:'/register',
data: JSON.stringify({name,password})
})
})
</script>
</body>
</html>


代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
<title>注册</title>
</head>
<body>
<form id="registerForm">
<div>
<label>用户名<input type="text" name="name"></label>
</div>
<div>
<label>密码<input type="password" name="password"></label>
</div>
<div>
<button type="submit">注册</button>
</div>
</form>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.0/jquery.min.js"></script>
<script>
const $form = $('#registerForm')
$form.on('submit',(e)=>{
e.preventDefault()
const name = $form.find('input[name=name]').val()
const password = $form.find('input[name=password]').val()
console.log(name)
console.log(password)
$.ajax({
method:'POST',
url:'/register',
contentType: 'text/json; charset=UTF-8',
data: JSON.stringify({name,password})
})
})
</script>
</body>
</html>

实现用户注册功能
修改server.js,后端获取用户名和密码
代码语言:javascript复制 if(path === "/register" && method === 'POST'){
response.setHeader('Content-Type','text/html')
response.end("很好")
}

代码语言:javascript复制var http = require('http')
var fs = require('fs')
var url = require('url')
var port = process.argv[2]
if(!port){
console.log('请指定端口号好不啦?nnode server.js 8888 这样不会吗?')
process.exit(1)
}
var server = http.createServer(function(request, response){
var parsedUrl = url.parse(request.url, true)
var pathWithQuery = request.url
var queryString = ''
if(pathWithQuery.indexOf('?') >= 0){ queryString = pathWithQuery.substring(pathWithQuery.indexOf('?')) }
var path = parsedUrl.pathname
var query = parsedUrl.query
var method = request.method
/******** 从这里开始看,上面不要看 ************/
console.log('有个傻子发请求过来啦!路径(带查询参数)为:' pathWithQuery)
if(path === "/register" && method === 'POST'){
response.setHeader('Content-Type','text/html')
const array = []
request.on('data',(chunk)=>{
array.push(chunk)
})
request.on('end',()=>{
console.log(array)
response.end("很好")
})
}else{
response.statusCode = 200
const filePath = path === '/' ? '/index.html' : path // 默认首页
const index = filePath.lastIndexOf('.')
const backend = filePath.substring(index)
const fileTypes = {
'.html':'text/html',
'.css':'text/css',
'.js':'text/javascript',
'.json':'application/json',
'.png':'image/png',
'.jpg':'image/jpeg',
'.jpeg':'image/jpeg',
'.gif':'image/gif'
}
response.setHeader('Content-Type', `${fileTypes[backend] || 'text/html'};charset=utf-8`)
console.log(backend)
let content
try {
content = fs.readFileSync(`public${filePath}`)
} catch (error) {
content = '文件:' filePath '不存在啊,大兄弟,你这是要上天啊?'
response.statusCode = 404
}
response.write(content)
response.end()
}
/******** 代码结束,下面不要看 ************/
})
server.listen(port)
console.log('监听 ' port ' 成功n请用在空中转体720度然后用电饭煲打开 http://localhost:' port)
获取到了,但是...是一堆乱码,emm...其实并不是乱码,是UTF-8字符集,我们给他合成字符串即可。

代码语言:javascript复制const string = Buffer.concat(array).toString()
console.log(string)

把获取到的字符串,变成对象,然后打印出来看看。
代码语言:javascript复制const obj = JSON.parse(string)
console.log(obj.name)
console.log(obj.password)

代码语言:javascript复制var http = require('http')
var fs = require('fs')
var url = require('url')
var port = process.argv[2]
if(!port){
console.log('请指定端口号好不啦?nnode server.js 8888 这样不会吗?')
process.exit(1)
}
var server = http.createServer(function(request, response){
var parsedUrl = url.parse(request.url, true)
var pathWithQuery = request.url
var queryString = ''
if(pathWithQuery.indexOf('?') >= 0){ queryString = pathWithQuery.substring(pathWithQuery.indexOf('?')) }
var path = parsedUrl.pathname
var query = parsedUrl.query
var method = request.method
/******** 从这里开始看,上面不要看 ************/
console.log('有个傻子发请求过来啦!路径(带查询参数)为:' pathWithQuery)
if(path === "/register" && method === 'POST'){
response.setHeader('Content-Type','text/html; charset=utf-8')
const userArray = JSON.parse(fs.readFileSync('./db/user.json'))
const array = []
request.on('data',(chunk)=>{
array.push(chunk)
})
request.on('end',()=>{
const string = Buffer.concat(array).toString()
const obj = JSON.parse(string)
const lastUSer = userArray[userArray.length -1]
const newUser = {
// 如果最后一个用户存在,那么就是最后一个用户的id 1,不存在就是1
id: lastUSer ? lastUSer.id 1: 1,
name: obj.name,
password: obj.password
}
userArray.push(newUser)
fs.writeFileSync('./db/user.json',JSON.stringify(userArray))
response.end()
})
}else{
response.statusCode = 200
const filePath = path === '/' ? '/index.html' : path // 默认首页
const index = filePath.lastIndexOf('.')
const backend = filePath.substring(index)
const fileTypes = {
'.html':'text/html',
'.css':'text/css',
'.js':'text/javascript',
'.json':'application/json',
'.png':'image/png',
'.jpg':'image/jpeg',
'.jpeg':'image/jpeg',
'.gif':'image/gif'
}
response.setHeader('Content-Type', `${fileTypes[backend] || 'text/html'};charset=utf-8`)
console.log(backend)
let content
try {
content = fs.readFileSync(`public${filePath}`)
} catch (error) {
content = '文件:' filePath '不存在啊,大兄弟,你这是要上天啊?'
response.statusCode = 404
}
response.write(content)
response.end()
}
/******** 代码结束,下面不要看 ************/
})
server.listen(port)
console.log('监听 ' port ' 成功n请用在空中转体720度然后用电饭煲打开 http://localhost:' port)
注册完,立马写入。

然后我们来完善后续,注册成功,那么我们就可以跳转到登录页面了,但是emm...登录页面还没有,我们先把代码写出来,写完之后,创建一个sigin.html
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
<title>注册</title>
</head>
<body>
<form id="registerForm">
<div>
<label>用户名<input type="text" name="name"></label>
</div>
<div>
<label>密码<input type="password" name="password"></label>
</div>
<div>
<button type="submit">注册</button>
</div>
</form>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.0/jquery.min.js"></script>
<script>
const $form = $('#registerForm')
$form.on('submit',(e)=>{
e.preventDefault()
const name = $form.find('input[name=name]').val()
const password = $form.find('input[name=password]').val()
console.log(name)
console.log(password)
$.ajax({
method:'POST',
url:'/register',
contentType: 'text/json; charset=UTF-8',
data: JSON.stringify({name,password})
}).then(()=>{
alert('注册成功')
location.href = '/sigin.html'
},()=>{})
})
</script>
</body>
</html>



实现用户登录功能
需求,我们需要做两个页面:
1.首页home.html,已经登录的用户可以看到自己的用户名 2.登录页sigin.html,让用户提交用户名和密码
home.html
代码语言:javascript复制<!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>
<p>
你好,{{ user.name }}
</p>
<p>
<a href="sigin.html">登录</a>
</p>
</body>
</html>
写一个登录页
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登录</title>
</head>
<body>
<form id="siginForm">
<div>
<label>用户名<input type="text" name="name"></label>
</div>
<div>
<label>密码<input type="password" name="password"></label>
</div>
<div>
<button type="submit">登录</button>
</div>
</form>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.0/jquery.min.js"></script>
<script>
const $form = $('#siginForm')
$form.on('submit',(e)=>{
e.preventDefault()
const name = $form.find('input[name=name]').val()
const password = $form.find('input[name=password]').val()
$.ajax({
method:'POST',
url:'/sigin',
contentType: 'text/json; charset=UTF-8',
data: JSON.stringify({name,password})
}).then(()=>{
alert('登录成功')
location.href = '/home.html'
},()=>{})
})
</script>
</body>
</html>
实现后端的逻辑
代码语言:javascript复制var http = require('http')
var fs = require('fs')
var url = require('url')
var port = process.argv[2]
if(!port){
console.log('请指定端口号好不啦?nnode server.js 8888 这样不会吗?')
process.exit(1)
}
var server = http.createServer(function(request, response){
var parsedUrl = url.parse(request.url, true)
var pathWithQuery = request.url
var queryString = ''
if(pathWithQuery.indexOf('?') >= 0){ queryString = pathWithQuery.substring(pathWithQuery.indexOf('?')) }
var path = parsedUrl.pathname
var query = parsedUrl.query
var method = request.method
/******** 从这里开始看,上面不要看 ************/
console.log('有个傻子发请求过来啦!路径(带查询参数)为:' pathWithQuery)
if(path === '/sigin' && method === 'POST'){
response.setHeader('Content-Type','text/html; charset=utf-8')
const userArray = JSON.parse(fs.readFileSync('./db/user.json'))
const array = []
request.on('data',(chunk)=>{
array.push(chunk)
})
request.on('end',()=>{
const string = Buffer.concat(array).toString()
const obj = JSON.parse(string)
const user = userArray.find((user)=> user.name === obj.name && user.password === obj.password)
if(user === undefined){
response.statusCode = 400
response.end('用户名密码不匹配')
}else{
response.statusCode = 200
response.end()
}
})
} else if(path === '/home.html'){
response.end('home')
} else if(path === "/register" && method === 'POST'){
response.setHeader('Content-Type','text/html; charset=utf-8')
const userArray = JSON.parse(fs.readFileSync('./db/user.json'))
const array = []
request.on('data',(chunk)=>{
array.push(chunk)
})
request.on('end',()=>{
const string = Buffer.concat(array).toString()
const obj = JSON.parse(string)
const lastUSer = userArray[userArray.length -1]
const newUser = {
// 如果最后一个用户存在,那么就是最后一个用户的id 1,不存在就是1
id: lastUSer ? lastUSer.id 1: 1,
name: obj.name,
password: obj.password
}
userArray.push(newUser)
fs.writeFileSync('./db/user.json',JSON.stringify(userArray))
response.end()
})
}else{
response.statusCode = 200
const filePath = path === '/' ? '/index.html' : path // 默认首页
const index = filePath.lastIndexOf('.')
const backend = filePath.substring(index)
const fileTypes = {
'.html':'text/html',
'.css':'text/css',
'.js':'text/javascript',
'.json':'application/json',
'.png':'image/png',
'.jpg':'image/jpeg',
'.jpeg':'image/jpeg',
'.gif':'image/gif'
}
response.setHeader('Content-Type', `${fileTypes[backend] || 'text/html'};charset=utf-8`)
console.log(backend)
let content
try {
content = fs.readFileSync(`public${filePath}`)
} catch (error) {
content = '文件:' filePath '不存在啊,大兄弟,你这是要上天啊?'
response.statusCode = 404
}
response.write(content)
response.end()
}
/******** 代码结束,下面不要看 ************/
})
server.listen(port)
console.log('监听 ' port ' 成功n请用在空中转体720度然后用电饭煲打开 http://localhost:' port)

瞎写,登录失败返回400

正常写,200,单击完确定就会跳转到首页。

我们修改一下home的页面,显示登录状态。
代码语言:javascript复制<!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>
<p>
{{ loginStatus }}
</p>
<p>
<a href="sigin.html">登录</a>
</p>
</body>
</html>
那么如何识别,用户是否登录过呢?因为我们在登录后,显示home页面,但是我们不登录,直接访问http://127.0.0.1:8888/home.html 也是一样呀。同样都能访问到home页面,和不需要登录有啥区别?
所以我们必须要识别 用户到底有没有登录,没有登录那么就去登录页面 ,登录过后,才能去home页面,直接访问home,直接跳转到登录页面。
Cookie介绍
定义: Cookie是服务器下发给浏览器的一段字符串,浏览器必须,保存这个Cookie(除非删除 用户),之后发起相同二级域名请求(任何请求)时,浏览器必须附上Cookie。
就相当于是一个令牌,登录成功就是皇上给你发了个令牌,但是只要进入京城,不管去哪里都要随身携带令牌,如果一旦令牌失效,对不起,再见,fire the hole...
再举个例子,公园的检票员,如何才能知道你能不能进呢?你是不是需要去买张票?买完票就相当于拿到了 Cookie,票=Cookie,有些公园里面有景区,进入景区或者xxx故居,还得再看看你的票,才能让你进,就是这个样子,所以只要你登录了,以后你不管访问哪个页面,都会带着Cookie去访问。
代码语言:javascript复制var http = require('http')
var fs = require('fs')
var url = require('url')
var port = process.argv[2]
if(!port){
console.log('请指定端口号好不啦?nnode server.js 8888 这样不会吗?')
process.exit(1)
}
var server = http.createServer(function(request, response){
var parsedUrl = url.parse(request.url, true)
var pathWithQuery = request.url
var queryString = ''
if(pathWithQuery.indexOf('?') >= 0){ queryString = pathWithQuery.substring(pathWithQuery.indexOf('?')) }
var path = parsedUrl.pathname
var query = parsedUrl.query
var method = request.method
/******** 从这里开始看,上面不要看 ************/
console.log('有个傻子发请求过来啦!路径(带查询参数)为:' pathWithQuery)
if(path === '/sigin' && method === 'POST'){
response.setHeader('Content-Type','text/html; charset=utf-8')
const userArray = JSON.parse(fs.readFileSync('./db/user.json'))
const array = []
request.on('data',(chunk)=>{
array.push(chunk)
})
request.on('end',()=>{
const string = Buffer.concat(array).toString()
const obj = JSON.parse(string)
const user = userArray.find((user)=> user.name === obj.name && user.password === obj.password)
if(user === undefined){
response.statusCode = 400
response.end('用户名密码不匹配')
}else{
response.statusCode = 200
response.setHeader('Set-Cookie','logined=1')
response.end()
}
})
} else if(path === '/home.html'){
response.end('home')
} else if(path === "/register" && method === 'POST'){
response.setHeader('Content-Type','text/html; charset=utf-8')
const userArray = JSON.parse(fs.readFileSync('./db/user.json'))
const array = []
request.on('data',(chunk)=>{
array.push(chunk)
})
request.on('end',()=>{
const string = Buffer.concat(array).toString()
const obj = JSON.parse(string)
const lastUSer = userArray[userArray.length -1]
const newUser = {
// 如果最后一个用户存在,那么就是最后一个用户的id 1,不存在就是1
id: lastUSer ? lastUSer.id 1: 1,
name: obj.name,
password: obj.password
}
userArray.push(newUser)
fs.writeFileSync('./db/user.json',JSON.stringify(userArray))
response.end()
})
}else{
response.statusCode = 200
const filePath = path === '/' ? '/index.html' : path // 默认首页
const index = filePath.lastIndexOf('.')
const backend = filePath.substring(index)
const fileTypes = {
'.html':'text/html',
'.css':'text/css',
'.js':'text/javascript',
'.json':'application/json',
'.png':'image/png',
'.jpg':'image/jpeg',
'.jpeg':'image/jpeg',
'.gif':'image/gif'
}
response.setHeader('Content-Type', `${fileTypes[backend] || 'text/html'};charset=utf-8`)
console.log(backend)
let content
try {
content = fs.readFileSync(`public${filePath}`)
} catch (error) {
content = '文件:' filePath '不存在啊,大兄弟,你这是要上天啊?'
response.statusCode = 404
}
response.write(content)
response.end()
}
/******** 代码结束,下面不要看 ************/
})
server.listen(port)
console.log('监听 ' port ' 成功n请用在空中转体720度然后用电饭煲打开 http://localhost:' port)


home页面获取Cookie
代码语言:javascript复制var http = require('http')
var fs = require('fs')
var url = require('url')
var port = process.argv[2]
if(!port){
console.log('请指定端口号好不啦?nnode server.js 8888 这样不会吗?')
process.exit(1)
}
var server = http.createServer(function(request, response){
var parsedUrl = url.parse(request.url, true)
var pathWithQuery = request.url
var queryString = ''
if(pathWithQuery.indexOf('?') >= 0){ queryString = pathWithQuery.substring(pathWithQuery.indexOf('?')) }
var path = parsedUrl.pathname
var query = parsedUrl.query
var method = request.method
/******** 从这里开始看,上面不要看 ************/
console.log('有个傻子发请求过来啦!路径(带查询参数)为:' pathWithQuery)
if(path === '/sigin' && method === 'POST'){
response.setHeader('Content-Type','text/html; charset=utf-8')
const userArray = JSON.parse(fs.readFileSync('./db/user.json'))
const array = []
request.on('data',(chunk)=>{
array.push(chunk)
})
request.on('end',()=>{
const string = Buffer.concat(array).toString()
const obj = JSON.parse(string)
const user = userArray.find((user)=> user.name === obj.name && user.password === obj.password)
if(user === undefined){
response.statusCode = 400
response.end('用户名密码不匹配')
}else{
response.statusCode = 200
response.setHeader('Set-Cookie','logined=1')
response.end()
}
})
} else if(path === '/home.html'){
const cookie = request.headers['cookie']
if(cookie === 'logined=1'){
const homeHtml = fs.readFileSync('./public/home.html').toString()
const string = homeHtml.replace('{{ loginStatus }}','已登录')
response.write(string)
} else{
const homeHtml = fs.readFileSync('./public/home.html').toString()
const string = homeHtml.replace('{{ loginStatus }}','未登录')
response.write(string)
}
response.end()
} else if(path === "/register" && method === 'POST'){
response.setHeader('Content-Type','text/html; charset=utf-8')
const userArray = JSON.parse(fs.readFileSync('./db/user.json'))
const array = []
request.on('data',(chunk)=>{
array.push(chunk)
})
request.on('end',()=>{
const string = Buffer.concat(array).toString()
const obj = JSON.parse(string)
const lastUSer = userArray[userArray.length -1]
const newUser = {
// 如果最后一个用户存在,那么就是最后一个用户的id 1,不存在就是1
id: lastUSer ? lastUSer.id 1: 1,
name: obj.name,
password: obj.password
}
userArray.push(newUser)
fs.writeFileSync('./db/user.json',JSON.stringify(userArray))
response.end()
})
}else{
response.statusCode = 200
const filePath = path === '/' ? '/index.html' : path // 默认首页
const index = filePath.lastIndexOf('.')
const backend = filePath.substring(index)
const fileTypes = {
'.html':'text/html',
'.css':'text/css',
'.js':'text/javascript',
'.json':'application/json',
'.png':'image/png',
'.jpg':'image/jpeg',
'.jpeg':'image/jpeg',
'.gif':'image/gif'
}
response.setHeader('Content-Type', `${fileTypes[backend] || 'text/html'};charset=utf-8`)
console.log(backend)
let content
try {
content = fs.readFileSync(`public${filePath}`)
} catch (error) {
content = '文件:' filePath '不存在啊,大兄弟,你这是要上天啊?'
response.statusCode = 404
}
response.write(content)
response.end()
}
/******** 代码结束,下面不要看 ************/
})
server.listen(port)
console.log('监听 ' port ' 成功n请用在空中转体720度然后用电饭煲打开 http://localhost:' port)

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Set-Cookie 设置cookie语法的网站,我们进去看看

一定要加上HttpOnly
禁止前端操作cookie
var http = require('http')
var fs = require('fs')
var url = require('url')
var port = process.argv[2]
if(!port){
console.log('请指定端口号好不啦?nnode server.js 8888 这样不会吗?')
process.exit(1)
}
var server = http.createServer(function(request, response){
var parsedUrl = url.parse(request.url, true)
var pathWithQuery = request.url
var queryString = ''
if(pathWithQuery.indexOf('?') >= 0){ queryString = pathWithQuery.substring(pathWithQuery.indexOf('?')) }
var path = parsedUrl.pathname
var query = parsedUrl.query
var method = request.method
/******** 从这里开始看,上面不要看 ************/
console.log('有个傻子发请求过来啦!路径(带查询参数)为:' pathWithQuery)
if(path === '/sigin' && method === 'POST'){
response.setHeader('Content-Type','text/html; charset=utf-8')
const userArray = JSON.parse(fs.readFileSync('./db/user.json'))
const array = []
request.on('data',(chunk)=>{
array.push(chunk)
})
request.on('end',()=>{
const string = Buffer.concat(array).toString()
const obj = JSON.parse(string)
const user = userArray.find((user)=> user.name === obj.name && user.password === obj.password)
if(user === undefined){
response.statusCode = 400
response.end('用户名密码不匹配')
}else{
response.statusCode = 200
response.setHeader('Set-Cookie','logined=1;HttpOnly')
response.end()
}
})
} else if(path === '/home.html'){
const cookie = request.headers['cookie']
if(cookie === 'logined=1'){
const homeHtml = fs.readFileSync('./public/home.html').toString()
const string = homeHtml.replace('{{ loginStatus }}','已登录')
response.write(string)
} else{
const homeHtml = fs.readFileSync('./public/home.html').toString()
const string = homeHtml.replace('{{ loginStatus }}','未登录')
response.write(string)
}
response.end()
} else if(path === "/register" && method === 'POST'){
response.setHeader('Content-Type','text/html; charset=utf-8')
const userArray = JSON.parse(fs.readFileSync('./db/user.json'))
const array = []
request.on('data',(chunk)=>{
array.push(chunk)
})
request.on('end',()=>{
const string = Buffer.concat(array).toString()
const obj = JSON.parse(string)
const lastUSer = userArray[userArray.length -1]
const newUser = {
// 如果最后一个用户存在,那么就是最后一个用户的id 1,不存在就是1
id: lastUSer ? lastUSer.id 1: 1,
name: obj.name,
password: obj.password
}
userArray.push(newUser)
fs.writeFileSync('./db/user.json',JSON.stringify(userArray))
response.end()
})
}else{
response.statusCode = 200
const filePath = path === '/' ? '/index.html' : path // 默认首页
const index = filePath.lastIndexOf('.')
const backend = filePath.substring(index)
const fileTypes = {
'.html':'text/html',
'.css':'text/css',
'.js':'text/javascript',
'.json':'application/json',
'.png':'image/png',
'.jpg':'image/jpeg',
'.jpeg':'image/jpeg',
'.gif':'image/gif'
}
response.setHeader('Content-Type', `${fileTypes[backend] || 'text/html'};charset=utf-8`)
console.log(backend)
let content
try {
content = fs.readFileSync(`public${filePath}`)
} catch (error) {
content = '文件:' filePath '不存在啊,大兄弟,你这是要上天啊?'
response.statusCode = 404
}
response.write(content)
response.end()
}
/******** 代码结束,下面不要看 ************/
})
server.listen(port)
console.log('监听 ' port ' 成功n请用在空中转体720度然后用电饭煲打开 http://localhost:' port)
辣么问题又来了,home.html只是知道你登录了,但是怎么知道你登录的是谁呢? 所以我们要把cookie跟user id 绑定。
把cookie替换成user id
home.html
代码语言:javascript复制<!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>
<p>
{{ user.name }}
{{ loginStatus }}
</p>
<p>
<a href="sigin.html">登录</a>
</p>
</body>
</html>
server.js
代码语言:javascript复制var http = require('http')
var fs = require('fs')
var url = require('url')
var port = process.argv[2]
if(!port){
console.log('请指定端口号好不啦?nnode server.js 8888 这样不会吗?')
process.exit(1)
}
var server = http.createServer(function(request, response){
var parsedUrl = url.parse(request.url, true)
var pathWithQuery = request.url
var queryString = ''
if(pathWithQuery.indexOf('?') >= 0){ queryString = pathWithQuery.substring(pathWithQuery.indexOf('?')) }
var path = parsedUrl.pathname
var query = parsedUrl.query
var method = request.method
/******** 从这里开始看,上面不要看 ************/
console.log('有个傻子发请求过来啦!路径(带查询参数)为:' pathWithQuery)
if(path === '/sigin' && method === 'POST'){
response.setHeader('Content-Type','text/html; charset=utf-8')
const userArray = JSON.parse(fs.readFileSync('./db/user.json'))
const array = []
request.on('data',(chunk)=>{
array.push(chunk)
})
request.on('end',()=>{
const string = Buffer.concat(array).toString()
const obj = JSON.parse(string)
const user = userArray.find((user)=> user.name === obj.name && user.password === obj.password)
if(user === undefined){
response.statusCode = 400
response.end('用户名密码不匹配')
}else{
response.statusCode = 200
response.setHeader('Set-Cookie',`user_id=${user.id};HttpOnly`)
response.end()
}
})
} else if(path === '/home.html'){
const cookie = request.headers['cookie']
let userId
try {
userId = cookie.split(';').filter(s => s.indexOf('user_id=')>=0)[0].split('=')[1]
} catch (error) {}
if(userId){
const userArray = JSON.parse(fs.readFileSync('./db/user.json'))
const user = userArray.find(user => user.id.toString() === userId)
const homeHtml = fs.readFileSync('./public/home.html').toString()
let string
if(user){
string = homeHtml.replace('{{ loginStatus }}','已登录')
.replace('{{ user.name }}',user.name)
}
response.write(string)
} else{
const homeHtml = fs.readFileSync('./public/home.html').toString()
const string = homeHtml.replace('{{ loginStatus }}','未登录')
.replace('{{ user.name }}','')
response.write(string)
}
response.end()
} else if(path === "/register" && method === 'POST'){
response.setHeader('Content-Type','text/html; charset=utf-8')
const userArray = JSON.parse(fs.readFileSync('./db/user.json'))
const array = []
request.on('data',(chunk)=>{
array.push(chunk)
})
request.on('end',()=>{
const string = Buffer.concat(array).toString()
const obj = JSON.parse(string)
const lastUSer = userArray[userArray.length -1]
const newUser = {
// 如果最后一个用户存在,那么就是最后一个用户的id 1,不存在就是1
id: lastUSer ? lastUSer.id 1: 1,
name: obj.name,
password: obj.password
}
userArray.push(newUser)
fs.writeFileSync('./db/user.json',JSON.stringify(userArray))
response.end()
})
}else{
response.statusCode = 200
const filePath = path === '/' ? '/index.html' : path // 默认首页
const index = filePath.lastIndexOf('.')
const backend = filePath.substring(index)
const fileTypes = {
'.html':'text/html',
'.css':'text/css',
'.js':'text/javascript',
'.json':'application/json',
'.png':'image/png',
'.jpg':'image/jpeg',
'.jpeg':'image/jpeg',
'.gif':'image/gif'
}
response.setHeader('Content-Type', `${fileTypes[backend] || 'text/html'};charset=utf-8`)
console.log(backend)
let content
try {
content = fs.readFileSync(`public${filePath}`)
} catch (error) {
content = '文件:' filePath '不存在啊,大兄弟,你这是要上天啊?'
response.statusCode = 404
}
response.write(content)
response.end()
}
/******** 代码结束,下面不要看 ************/
})
server.listen(port)
console.log('监听 ' port ' 成功n请用在空中转体720度然后用电饭煲打开 http://localhost:' port)


但是,有一个大大大大大大大的BUG,就是用户可以篡改user id


我们改成2,然后刷新页面

卧槽,如果我知道MHT的QQ用户id岂不是我直接登录他的QQ号了?
使用session保存用户信息
为了修改大bug我们必须要使用session
其实,我们有两个思路
代码语言:javascript复制## 思路一:加密
# 将user id加密发送给前端,后端 读取user id时解密,此法可行,但是有安全漏洞。
# 漏洞:加密后内容可无限期使用
# 解决办法:JWT(想知道嘛?想知道呀,后面再讲)
## 思路二:把信息隐藏在服务器
# 把用户信息放在服务器的某个[x]地方,可以是数据库,可以是文件,可以是redis,可以是memcache,可以是...
# 不管放在哪里,再给这个信息一个随机的id,把随机的id发送给浏览器,后端下次读取到id的时候,通过x[id]获取用户信息,x是什么?x就是我上面说的redis,memcache,MySQL,文件,等地方。
# 想想为什么,用户无法篡改id,因为id很长,且随机。
# 所以,这个x又被叫做session(会话)
# 以后我们还会做,会话保持
创建一个session文件

session.json
代码语言:javascript复制{
"123123123123213123123123":{"user_id":1}
}

代码原来的 user_id
,改成 session_id
var http = require('http')
var fs = require('fs')
var url = require('url')
var port = process.argv[2]
if(!port){
console.log('请指定端口号好不啦?nnode server.js 8888 这样不会吗?')
process.exit(1)
}
var server = http.createServer(function(request, response){
var parsedUrl = url.parse(request.url, true)
var pathWithQuery = request.url
var queryString = ''
if(pathWithQuery.indexOf('?') >= 0){ queryString = pathWithQuery.substring(pathWithQuery.indexOf('?')) }
var path = parsedUrl.pathname
var query = parsedUrl.query
var method = request.method
/******** 从这里开始看,上面不要看 ************/
const session = JSON.parse(fs.readFileSync('./session.json').toString())
console.log('有个傻子发请求过来啦!路径(带查询参数)为:' pathWithQuery)
if(path === '/sigin' && method === 'POST'){
response.setHeader('Content-Type','text/html; charset=utf-8')
const userArray = JSON.parse(fs.readFileSync('./db/user.json'))
const array = []
request.on('data',(chunk)=>{
array.push(chunk)
})
request.on('end',()=>{
const string = Buffer.concat(array).toString()
const obj = JSON.parse(string)
const user = userArray.find((user)=> user.name === obj.name && user.password === obj.password)
if(user === undefined){
response.statusCode = 400
response.end('用户名密码不匹配')
}else{
response.statusCode = 200
const random = Math.random()
session[random] = {user_id: user.id}
fs.writeFileSync('./session.json',JSON.stringify(session))
response.setHeader('Set-Cookie',`session_id=${random};HttpOnly`)
}
response.end()
})
} else if(path === '/home.html'){
const cookie = request.headers['cookie']
let sessionId
try {
sessionId = cookie.split(';').filter(s => s.indexOf('session_id=')>=0)[0].split('=')[1]
} catch (error) {}
if(sessionId && session[sessionId]){
const userId = session[sessionId].user_id
const userArray = JSON.parse(fs.readFileSync('./db/user.json'))
const user = userArray.find(user => user.id === userId)
const homeHtml = fs.readFileSync('./public/home.html').toString()
let string = ''
if(user){
string = homeHtml.replace('{{ loginStatus }}','已登录')
.replace('{{ user.name }}',user.name)
}
response.write(string)
} else{
const homeHtml = fs.readFileSync('./public/home.html').toString()
const string = homeHtml.replace('{{ loginStatus }}','未登录')
.replace('{{ user.name }}','')
response.write(string)
}
response.end()
} else if(path === "/register" && method === 'POST'){
response.setHeader('Content-Type','text/html; charset=utf-8')
const userArray = JSON.parse(fs.readFileSync('./db/user.json'))
const array = []
request.on('data',(chunk)=>{
array.push(chunk)
})
request.on('end',()=>{
const string = Buffer.concat(array).toString()
const obj = JSON.parse(string)
const lastUSer = userArray[userArray.length -1]
const newUser = {
// 如果最后一个用户存在,那么就是最后一个用户的id 1,不存在就是1
id: lastUSer ? lastUSer.id 1: 1,
name: obj.name,
password: obj.password
}
userArray.push(newUser)
fs.writeFileSync('./db/user.json',JSON.stringify(userArray))
response.end()
})
}else{
response.statusCode = 200
const filePath = path === '/' ? '/index.html' : path // 默认首页
const index = filePath.lastIndexOf('.')
const backend = filePath.substring(index)
const fileTypes = {
'.html':'text/html',
'.css':'text/css',
'.js':'text/javascript',
'.json':'application/json',
'.png':'image/png',
'.jpg':'image/jpeg',
'.jpeg':'image/jpeg',
'.gif':'image/gif'
}
response.setHeader('Content-Type', `${fileTypes[backend] || 'text/html'};charset=utf-8`)
console.log(backend)
let content
try {
content = fs.readFileSync(`public${filePath}`)
} catch (error) {
content = '文件:' filePath '不存在啊,大兄弟,你这是要上天啊?'
response.statusCode = 404
}
response.write(content)
response.end()
}
/******** 代码结束,下面不要看 ************/
})
server.listen(port)
console.log('监听 ' port ' 成功n请用在空中转体720度然后用电饭煲打开 http://localhost:' port)


我们来篡改一下。。。

刷新页面,立马变成未登录。