确保电脑已安装node环境以及postman软件。
实现登录注册功能需要用到以下模块:
1、http模块 //提供http服务 实现服务器
2、url模块 //把url网址解析为一个对象
3、querystring模块//内置querystring parse decode encode四个模块
4、uuid模块//第三方模块,需要安装。生成一个32位的id(不重复)
uuid模块和后面拓展的md5模块都需要自己安装
安装步骤如下:
打开编辑器终端,输入以下代码
npm i uuid -S //安装uuid模块库
npm i md5 -S //安装md5模块库
自动监听对应的文件更新:
npm i nodemon -g
导入模块
//导入模块
const http = require('http') //导入http模块
const { parse } = require('url') //导入url模块
//内置querystring parse decode encode
const { decode } = require('querystring')
//生成一个32位的id(不重复的)
const { v4 } = require('uuid')
创建一个users数组来装对应的用户
这里的用户信息,可随意更改或增加。
let users = [{
id: 1,
username: 'jack',
password: '123456',
sex: '男',
address: '中国北京',
createTime: new Date('2022/10/08')
}, {
id: 2,
username: 'tom',
password: '123456',
sex: '男',
address: '中国上海',
createTime: new Date('2022/10/18')
}]
创建服务
这一步很重要,要设置响应头,获取路由地址,根据路由地址进行判断。
http.createServer((req, res) => {
//设置响应头
res.setHeader('content-type', 'text/json;charset=utf-8')
//获取路由地址
let router = parse(req.url).pathname
//参数接收的变量
let params = ''
//根据路由的路径进行判断
switch (router) {
case "/login": //登录 post
//获取数据 body里面 观察者模式(event对象 http模块里面导入了event模块)
//body里面的数据是分段传递的
//监听请求数据的传递
req.on('data', (chunk) => {
params += chunk
})
//监听请求结束
req.on('end', () => {
//queryString 自动将对应的请求字符串转为对象
let {
username,
password
} = decode(params)
//根据获取的参数进行对应的操作(验证)
let filter = users.filter(user => {
return username == user.username && password == user.password
})
if (filter[0]) {
res.write(JSON.stringify({
code: '200',
message: '登录成功',
data: filter[0]
}))
} else {
res.write(JSON.stringify({
code: '200',
message: '登录失败',
data: null
}))
}
res.end()
})
break;
case "/register": //注册 post
//获取数据
req.on('data', (chunk) => {
params += chunk
})
req.on('end', () => {
//将对应的数据转换对象
let {
username,
password,
sex,
address
} = decode(params)
//判断当前用户是否已经注册
if (users.some(user => user.username == username)) {
//当前用户已经存在
res.write(JSON.stringify({
code: 200,
message: '当前用户已经注册',
data: null
}))
} else {
//创建一个新的用户
let user = {
id: v4(),
username,
password,
sex: sex ? sex : '男',
address: address ? address : '中国北京',
createTime: new Date()
}
//添加用户
users.push(user)
res.write(JSON.stringify({
code: 200,
message: '注册成功',
data: user
}))
}
res.end()
})
break;
case "/searchByID": //根据id查找对应的用户 get
//监听请求数据传递 获取传递的数据id http://127.0.0.1:9999/searchByID?id=1
// req.url存在传递的数据 对于的数据里面?传递的参数进行提取
//得到get传递的参数
params = parse(req.url, true).query
//通过参数去找对应的uers里面的数据 返回对应的数据
let filterArr = users.filter(user => user.id == params.id)
if (filterArr[0]) { //有这个id
//只能写字符串和buffer类型
res.write(JSON.stringify({
code: 200,
message: 'OK',
data: filterArr[0]
}))
} else { //没有这个id
res.write(JSON.stringify({
code: 200,
message: 'OK',
data: null
}))
}
res.end()
break;
}
}).listen('9999', '127.0.0.1', () => {
console.log('server is running,at 127.0.0.1:9999')
})//监听端口号 判断是否在运行
最后一步 提取对应url地址的数据 返回参数对象
const queryByUrl = (url) => {
let params = {}
//http://127.0.0.1:9999/searchByID?id=1&name='jack' ===> {id:1}
let strArr = url.split('?')[1].split('&') //id=1 name='jack'
//遍历字符串数组
strArr.forEach(str => {
params[str.split('=')[0]] = str.split('=')[1]
});
return params
}
到这就全部完成了。
在编辑器终端运行你的js文件,然后打开postman软件发送请求,得到结果。
测试
1、输入jack的用户名和密码,提示“登录成功”,并且返回相关信息。
因为没有jack2这位用户,故而提示“登录失败”。
2、注册新的用户sure,只填写了用户名和密码,其余信息是默认的。
3、searchByID查找id为2的用户tom,并返回tom的相关信息。
拓展加密功能
上面实现的登录与注册的密码都是暴露出来的,极不安全,接下来说明使用md5模块来对密码进行简单的加密。
安装好后(安装方式在本文开头提到)导入模块:
const md5 = require('md5')
主要实现代码:
//根据获取的参数进行对应的操作(验证)
let filter = users.filter(user => {
return username == user.username && md5(password+user.slat) == user.password
})
拓展后的JS全部代码
//实现登录注册功能
//导入模块
const http = require('http')
const { parse } = require('url')
//内置querystring parse decode encode
const { decode } = require('querystring')
//第三方模块 uuid 生成id的 生成一个32位的id(不重复的)
const { v4 } = require('uuid')
const { resolve } = require('path')
//导入加密的模块 md5 (hash加密法 被破解 加盐(为了安全))
const md5 = require('md5')
//创建一个users数组来装对应的用户
let users = []
//创建服务
http.createServer((req, res) => {
//设置响应头
res.setHeader('content-type', 'text/json;charset=utf-8')
//解决跨域问题
res.setHeader('Access-Control-Allow-Origin', '*')
res.setHeader('Access-Control-Allow-Origin-Method', '*')
//解构拿出对应的路由地址和get的参数
let {
pathname,
query
} = parse(req.url, true)
//根据路由的路径进行判断
switch (pathname) {
case "/login": //登录 post
getPostParams(req).then(({
username,
password
}) => {
//根据获取的参数进行对应的操作(验证)
let filter = users.filter(user => {
return username == user.username && md5(password + user.slat) == user.password
})
if (filter[0]) {
res.write(JSON.stringify({
code: '200',
message: '登录成功',
data: filter[0]
}))
} else {
res.write(JSON.stringify({
code: '200',
message: '登录失败',
data: null
}))
}
res.end()
})
break;
case "/register": //注册 post
getPostParams(req).then(({
username,
password,
sex,
address
}) => {
//判断当前用户是否已经注册
if (users.some(user => user.username == username)) {
//当前用户已经存在
res.write(JSON.stringify({
code: 200,
message: '当前用户已经注册',
data: null
}))
} else {
let slat = Math.ceil(Math.random() * 1000 + 1000).toString(36)
//创建一个新的用户
let user = {
id: v4(),
username,
password: md5(password + slat),
sex: sex ? sex : '男',
address: address ? address : '中国北京',
createTime: new Date(),
slat //为了解密
}
//添加用户
users.push(user)
res.write(JSON.stringify({
code: 200,
message: '注册成功',
data: user
}))
}
res.end()
})
break;
case "/searchByID": //根据id查找对应的用户 get
//监听请求数据传递 获取传递的数据id http://127.0.0.1:9999/searchByID?id=1
// req.url存在传递的数据 对于的数据里面?传递的参数进行提取
// console.log(queryByUrl(req.url));
//得到get传递的参数
// let params = queryByUrl(req.url)
//通过参数去找对应的uers里面的数据 返回对应的数据
let filterArr = users.filter(user => user.id == query.id)
if (filterArr[0]) { //有这个id
//只能写字符串和buffer类型
res.write(JSON.stringify({
code: 200,
message: 'OK',
data: filterArr[0]
}))
} else { //没有这个id
res.write(JSON.stringify({
code: 200,
message: 'OK',
data: null
}))
}
res.end()
break;
}
}).listen('9999', '127.0.0.1', () => {
console.log('server is running,at 127.0.0.1:9999')
})
//封装返回对应的post请求的数据
const getPostParams = (req) => {
return new Promise((resolve, reject) => {
let params = ''
//获取数据 body里面 观察者模式(event对象 http模块里面导入了event模块)
//body里面的数据是分段传递的
//监听请求数据的传递
req.on('data', (chunk) => {
params += chunk
})
//监听请求结束
req.on('end', () => {
//queryString 自动将对应的请求字符串转为对象
resolve(decode(params))
})
//监听请求出错
req.on('error', (error) => {
reject(error)
})
})
}
HTML全部代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text">
<input type="password">
<button>登录</button>
<script>
//获取登录按钮
let btn = document.querySelector('button')
let inputs = document.querySelectorAll('input')
//给登录按钮添加点击事件
btn.onclick = () => {
//获取输入框的值
let xhr = new XMLHttpRequest()
xhr.open('post', 'http://127.0.0.1:9999/login')
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
xhr.send(`username=${inputs[0].value}&password=${inputs[1].value}`)
xhr.onreadystatechange = () => {
if (xhr.readyState == 4 && xhr.status == '200') {
console.log(JSON.parse(xhr.responseText));
}
}
}
</script>
</body>
</html>
最终效果如下图所示:
id 为自动生成的
密码为加密过的