欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

node.js實(shí)現(xiàn)簡單登錄注冊功能

 更新時(shí)間:2022年04月26日 14:57:21   作者:前端攻城fff  
這篇文章主要為大家詳細(xì)介紹了node.js實(shí)現(xiàn)簡單登錄注冊功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了node.js實(shí)現(xiàn)簡單登錄注冊的具體代碼,供大家參考,具體內(nèi)容如下

1、首先需要一個(gè)sever模塊用于引入路由,引入連接數(shù)據(jù)庫的模塊,監(jiān)聽服務(wù)器
2、要有model層,里面寫數(shù)據(jù)庫連接模塊和數(shù)據(jù)庫的各種model(表),并導(dǎo)出model對象
3、工具類utils,里面存放一些功能的模塊,并且封裝后導(dǎo)出 ,例如發(fā)送驗(yàn)證碼的功能
4、寫路由,需要對數(shù)據(jù)庫操作就使用導(dǎo)出的model對象,需要功能模塊就使用導(dǎo)出的功能對象
隨后返回這個(gè)路由,在sever里引入
5、生成api文檔

sever模塊

//實(shí)現(xiàn)登錄注冊,要先自己寫路由放在本地的服務(wù)器上
const express=require('express');
//登錄注冊需要連接到服務(wù)器,連接的邏輯單獨(dú)為一個(gè)db包,這里面放著和數(shù)據(jù)庫有關(guān)的,比如說數(shù)據(jù)庫的表,數(shù)據(jù)庫的連接
//這里只需要引入連接上述包的連接模塊即實(shí)現(xiàn)連接
const db=require('./db/connect');

//實(shí)例化express模塊,這里的實(shí)例化對象就是用來操作路由啊使用中間件之類的,都是它
const app=express();

//引入解析請求體的中間件模塊,方便路由里可以直接使用數(shù)據(jù)
const bodyparser=require('body-parser');
//使用這里面的解析請求體的方法
//這里use里面使用的是中間件模塊的方法,所以里面是點(diǎn)---------
app.use(bodyparser.urlencoded({extended:false}))
app.use(bodyparser.json())


//下面就是連接路由,先去寫下路由,之后在那里導(dǎo)出,這里就可以連接到了
//router里面存放的是全部的不同的路由
//在使用路由之前需要引入能解析請求體的中間件
//引入路由
const userRouter=require('./router/userRouter')
app.use('/user',userRouter);


//開啟端口號(hào)為3000的本地服務(wù)器
app.listen(3000,()=>{
? ? console.log("服務(wù)器已開啟");


})

數(shù)據(jù)庫model包

1.根目錄下的數(shù)據(jù)庫連接

//這個(gè)模塊不需要導(dǎo)出什么,其他地方引入這個(gè)模塊就自動(dòng)執(zhí)行里面的代碼,不需要返回的數(shù)據(jù)進(jìn)行下一步操作
//因此不需要導(dǎo)出
const mongoose=require('mongoose');
mongoose.connect('mongodb://localhost/first');//連接到哪一個(gè)數(shù)據(jù)庫
let db=mongoose.connection;//數(shù)據(jù)庫連接后的對象,以便于后續(xù)對連接過程的監(jiān)聽
db.on("error",console.error.bind(console,"連接異常"));
db.once("open",()=>{
? ? console.log("連接成功");
})

2.model模塊(表)

//對數(shù)據(jù)庫操作,需要mongoose模塊
const mongoose=require('mongoose');

//由于前面已經(jīng)連接到數(shù)據(jù)庫了,這里就可以直接創(chuàng)建schema對象了
const userSchema=mongoose.Schema({
? ? us:{type:String,required:true},
? ? ps:{type:String,required:true},
? ? age:Number,
? ? sex:{type:Number,default:0}
})

//這里需要對上面創(chuàng)建的表頭(字段)集合轉(zhuǎn)化為模型,即集合為一張表
//并返回一個(gè)對象,方便后續(xù)對表的操作,這里的對象需要導(dǎo)出,方便在其他模塊使用
//這里導(dǎo)出,是為了在路由里使用這個(gè)對象對數(shù)據(jù)庫進(jìn)行操作
const User=mongoose.model("users",userSchema);//使用model方法轉(zhuǎn)化,第一個(gè)參數(shù)是表名,第二個(gè)參數(shù)是需要轉(zhuǎn)化的模型
module.exports=User;

工具類utils

//utils是工具類的包,那么發(fā)送郵件的程序算是一個(gè)工具
//這里將發(fā)送的方法封裝并導(dǎo)出
const nodemailer=require('nodemailer');

//使用node方法創(chuàng)建發(fā)送的對象,接下來發(fā)送的方法肯定是該對象操作的
//創(chuàng)建發(fā)送對象基本都是固定格式
let transporter=nodemailer.createTransport({
? ? host:"smtp.qq.com",//發(fā)送方使用的郵箱
? ? port:465,//端口號(hào),可以在lib/well-known/service.json下找到這些信息
? ? secure:true,
? ? auth:{
? ? ? ? user:"1507337624@qq.com",
? ? ? ? pass:"" ? //這里不是郵箱密碼,而是郵箱開始第三方發(fā)送時(shí)給的驗(yàn)證碼
? ? }
})

//這里將發(fā)送的方法封裝,因?yàn)橹恍枰獙?dǎo)出這個(gè)方法,其他并不需要導(dǎo)出

function send(mail,code){
? ? //郵件信息
? ? let mailContent={
? ? ? ? from:'<1507337624@qq.com>',
? ? ? ? to:mail,
? ? ? ?subject:"驗(yàn)證碼 ",
? ? ? ?text:`您的驗(yàn)證碼是$[code],有效期五分鐘`
? ? }
? ? //這里的發(fā)送是異步的,發(fā)送成功與否只有回調(diào)函數(shù)里才知道,那么總不能發(fā)送成功后的代碼都寫在這個(gè)工具里吧
? ? //這只是個(gè)工具類,發(fā)送成功和失敗返回就行,誰用就誰處理
? ? //那么返回回調(diào)函數(shù)的失敗或者成功就要promise對象了,這里直接給發(fā)送的結(jié)果返回一個(gè)promise對象
? ? return new Promise((resolve,reject)=>{
? ? ? ? transporter.sendMail(mailContent,(err,data)=>{
? ? ? ? ? ? //錯(cuò)誤優(yōu)先,err默認(rèn)為null,另一個(gè)參數(shù)data包含了發(fā)送的一系列信息,狀態(tài),數(shù)據(jù)之類
? ? ? ? ? ? if(err){
? ? ? ? ? ? ? ? //執(zhí)行reject就意味著錯(cuò)誤,promise就會(huì)走catch
? ? ? ? ? ? ? ? reject()
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? resolve()
? ? ? ? ? ? }
? ? ? ? })
? ? })
}
module.exports={send}//這里返回的是一個(gè)對象,里面有一個(gè)屬性是send,而不是直接返回send方法本身,其實(shí)兩者都可以,但是規(guī)范上來說更多的是這個(gè)

核心路由router

這里寫接收并且處理請求的具體方法

//創(chuàng)建一個(gè)路由就要先實(shí)例化express下創(chuàng)建路由的方法
const express=require('express');
const router=express.Router();//注意這里的router是方法,需要括號(hào)
//登錄注冊等需要對數(shù)據(jù)庫進(jìn)行操作,這里需要對應(yīng)的model,先去創(chuàng)建一個(gè)model
//創(chuàng)建好了,可以引入了
const User=require("../db/model/userModel");

//注冊還需要郵箱驗(yàn)證,那么郵箱驗(yàn)證是一個(gè)單獨(dú)的功能,也就是需要實(shí)現(xiàn)的工具類的功能
//所以需要單獨(dú)一個(gè)包存放工具類功能,之后需要的時(shí)候引入就可以了,這里先去寫
//好了寫完了,下面可以導(dǎo)入了
const Mail=require('../utils/mail');
//那么問題來了,導(dǎo)入之后在哪里調(diào)用,發(fā)送郵箱驗(yàn)證碼也是一個(gè)請求吧
//既然是請求就應(yīng)該有對應(yīng)的接口,因?yàn)楫吘故窃谟脩糇陨险埱蟀l(fā)送驗(yàn)證碼,所以歸在用戶路由下

//創(chuàng)建一個(gè)全局變量用于保存驗(yàn)證碼信息,和注冊的郵箱是對應(yīng)的,因此這個(gè)變量是對象,注冊的郵箱作為屬性
const mailCodes={}

//接下來就可以寫路由的接口了
//
//注冊接口,生成 接口文檔
/**
?* @api {post} /user/register 用戶注冊
?* @apiName 用戶注冊
?* @apiGroup User
?*
?* @apiParam {String} us 用戶名
?* @apiParam {String} ps 密碼
?* @apiParam {String} mailCode 驗(yàn)證碼
?*
?* @apiSuccess {String} firstname Firstname of the User.
?* @apiSuccess {String} lastname ?Lastname of the User.
?*/
//這里需要對post請求的body分析,需要body-parser中間件,
//但是這里只返回給serve路由 ,因此要在server層引入
router.post('/register',(req,res)=>{
? ? let{us,ps,mailCode}=req.body;

? ? //先判斷us和ps還有驗(yàn)證碼是否都輸入了,如果沒輸入完成直接就終止執(zhí)行
? ? if(!us||!ps||!mailCode)return res.send({err:-1,msg:"參數(shù)錯(cuò)誤"})

? ? //將保存的驗(yàn)證碼對應(yīng)的us屬性的值與傳來的驗(yàn)證碼比較,不對的話直接就終止了,不需要再往下進(jìn)行了
? ? if(mailCodes[us]!=mailCode)return res.send({err:-4,msg:"驗(yàn)證碼不正確"})

? ? //接下來需要判斷用戶名是否存在,不存在的話就可以注冊
? ? User.find({us})
? ? ? ? .then((data)=>{
? ? ? ? ? ? //只要去找了,就會(huì)返回?cái)?shù)據(jù),沒找到返回空,否則返回找到的數(shù)據(jù)
? ? ? ? ? ? if (data.length==0){
? ? ? ? ? ? ? ? //沒有的話就可以注冊了,那么下一步操作也是需要返回promise對象,方便鏈?zhǔn)秸{(diào)用
? ? ? ? ? ? ? ? //這里涉及到對數(shù)據(jù)庫的操作,需要引入數(shù)據(jù)庫的model,在頂部引入
? ? ? ? ? ? ? ?return ?User.insertMany({us,ps})
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? //如果存在的話就不能注冊,那么就需要返回錯(cuò)誤信息
? ? ? ? ? ? ? ? return res.send({err:-3,msg:"該用戶名已存在"})
? ? ? ? ? ? }
? ? ? ? })
? ? ? ? //之前說過對數(shù)據(jù)庫的操作默認(rèn)返回一個(gè)promise對象,可以直接then,catch
? ? ? ? //復(fù)習(xí)一下對數(shù)據(jù)庫操作返回的promise是內(nèi)部定義的,then里面回調(diào)參數(shù)是data,即查詢或者插入的數(shù)據(jù)之類
? ? ? ? //而catch里面的參數(shù)err就是錯(cuò)誤信息
? ? ? ? .then(()=>{
? ? ? ? ? ? //這里的res.send是像前臺(tái)返回的信息,前面路由創(chuàng)建的學(xué)習(xí)說過了
? ? ? ? ? ? res.send({err:0,msg:"注冊ok"})
? ? ? ? })
? ? ? ? //無論是幾個(gè)鏈?zhǔn)秸{(diào)用,只要有異常都會(huì)來到這里
? ? ? ? .catch((err)=>{
? ? ? ? ? ? //這里的錯(cuò)誤不是注冊過程中重復(fù)不能注冊的錯(cuò)誤,這里應(yīng)該是數(shù)據(jù)庫連接異常的錯(cuò)誤這類
? ? ? ? ? ? res.send({err:-1,msg:"內(nèi)部錯(cuò)誤"})
? ? ? ? })

})

//登錄接口,接口文檔
/**
?* @api {post} /user/login ?用戶登錄
?* @apiName 用戶登錄
?* @apiGroup User
?*
?* @apiParam {String} us 用戶名
?* @apiParam {String} ps 密碼
?*
?* @apiSuccess {String} firstname Firstname of the User.
?* @apiSuccess {String} lastname ?Lastname of the User.
?*/
router.post("/login",(req,res)=>{
? ? let{us,ps}=req.body;

? ? //先判斷us和ps還有驗(yàn)證碼是否都輸入了,如果沒輸入完成直接就終止執(zhí)行
? ? if(!us||!ps)return res.send({err:-1,msg:"參數(shù)錯(cuò)誤"})


? ? ? ? //下面的find直接就在數(shù)據(jù)庫里尋找了,找到了返回?cái)?shù)據(jù),否則返回空(都是一個(gè)數(shù)組)
? ? ? ? User.find({us,ps})
? ? ? ? .then((data)=>{
? ? ? ? ? ? //如果找到了,則data的長度大于0,反之是沒找到
? ? ? ? ? ? if(data.length>0){
? ? ? ? ? ? ? ? res.send({err:0,msg:"登錄 OK"})
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? res.send({err:-1,msg:"用戶名或密碼錯(cuò)誤"})
? ? ? ? ? ? }
? ? ? ? })
? ? ? ? .catch((err)=>{
? ? ? ? ? ? res.send({err:-2,msg:"內(nèi)部錯(cuò)誤"})
? ? ? ? })

})

//接口文檔
/**
?* @api {post} /user/getCode ?獲取驗(yàn)證碼
?* @apiName 獲取驗(yàn)證碼
?* @apiGroup User
?*
?* @apiParam {String} us 用戶名
?*
?* @apiSuccess {String} firstname Firstname of the User.
?* @apiSuccess {String} lastname ?Lastname of the User.
?*/
//為什么會(huì)在這里寫一個(gè)發(fā)送郵箱驗(yàn)證碼的接口,它原本是一個(gè)方法,
// 但是請求后臺(tái)發(fā)送一個(gè)驗(yàn)證碼,并且傳入需要發(fā)送的郵箱,這本身就是一個(gè)完整的請求
//想一下,我在頁面上注冊的時(shí)候,輸入郵箱后點(diǎn)擊發(fā)送驗(yàn)證碼,這不是一個(gè)請求嗎,那不就需要一個(gè)接口嗎
router.post('/getCode',(req,res)=>{
? ? let {us}=req.body;//從請求體中找到需要發(fā)送的地址
? ? //這里利用隨機(jī)函數(shù)生成隨機(jī)數(shù)
? ? //強(qiáng)轉(zhuǎn)為整數(shù),這里之所以用變量保存起來,是因?yàn)橄旅嫘枰獙Ⅱ?yàn)證碼和發(fā)送的對象一起保存
? ? //發(fā)送對象作為屬性,驗(yàn)證碼為值,因?yàn)楹罄m(xù)需要比較驗(yàn)證碼,所以需要一個(gè)全局變量來保存,去上面創(chuàng)建
? ? let code=parseInt(Math.random()*10000)
? ? Mail.send(us,code)
? ? ? ? .then(()=>{
? ? ? ? ? ? //發(fā)送成功要返回信息,并且保存驗(yàn)證碼
? ? ? ? ? ? //驗(yàn)證碼一定在發(fā)送成功后保存,否則隨便輸入一個(gè)不管發(fā)送成功還是失敗都保存的話會(huì)大量占用空間
? ? ? ? ? ? res.send({err:0,msg:"驗(yàn)證碼發(fā)送成功"})
? ? ? ? ? ? mailCodes[us]=code;//將郵箱和驗(yàn)證碼一一對應(yīng)保存起來,方便其他接口的比較
? ? ? ? })
? ? ? ? .catch(()=>{
? ? ? ? ? ? res.send({err:-3,msg:"發(fā)送失敗,請檢查郵箱是否正確或網(wǎng)絡(luò)連接"})
? ? ? ? })

})
//路由寫完了,現(xiàn)在可以把該數(shù)據(jù)庫返回到操作層了
module.exports=router;

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 使用node.js 獲取客戶端信息代碼分享

    使用node.js 獲取客戶端信息代碼分享

    本文給大家分享一段使用node.js 獲取客戶端信息的代碼,非常的簡潔,推薦給大家。
    2014-11-11
  • nodejs個(gè)人博客開發(fā)第五步 分配數(shù)據(jù)

    nodejs個(gè)人博客開發(fā)第五步 分配數(shù)據(jù)

    這篇文章主要為大家詳細(xì)介紹了nodejs個(gè)人博客開發(fā)的分配數(shù)據(jù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • node.js中的fs.writeFile方法使用說明

    node.js中的fs.writeFile方法使用說明

    這篇文章主要介紹了node.js中的fs.writeFile方法使用說明,本文介紹了fs.writeFile的方法說明、語法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • node命令以及切換node版本詳細(xì)步驟

    node命令以及切換node版本詳細(xì)步驟

    這篇文章主要給大家介紹了關(guān)于node命令以及切換node版本的相關(guān)資料,在使用node命令切換node版本時(shí)可以使用nvm(Node?Version?Manager)工具來管理不同版本的node,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • node.js中的buffer.fill方法使用說明

    node.js中的buffer.fill方法使用說明

    這篇文章主要介紹了node.js中的buffer.fill方法使用說明,本文介紹了buffer.fill的方法說明、語法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • nodejs初始化init的示例代碼

    nodejs初始化init的示例代碼

    今天小編就為大家分享一篇nodejs初始化init的示例代碼,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • node.js抓取并分析網(wǎng)頁內(nèi)容有無特殊內(nèi)容的js文件

    node.js抓取并分析網(wǎng)頁內(nèi)容有無特殊內(nèi)容的js文件

    nodejs獲取網(wǎng)頁內(nèi)容綁定data事件,獲取到的數(shù)據(jù)會(huì)分幾次相應(yīng),如果想全局內(nèi)容匹配,需要等待請求結(jié)束,在end結(jié)束事件里把累積起來的全局?jǐn)?shù)據(jù)進(jìn)行操作,本文給大家介紹node.js抓取并分析網(wǎng)頁內(nèi)容有無特殊內(nèi)容的js文件,需要的朋友參考下
    2015-11-11
  • node通過express搭建自己的服務(wù)器

    node通過express搭建自己的服務(wù)器

    本篇文章主要介紹了node通過express搭建自己的服務(wù)器 ,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • Node 升級(jí)到最新穩(wěn)定版的方法分享

    Node 升級(jí)到最新穩(wěn)定版的方法分享

    今天小編就為大家分享一篇Node 升級(jí)到最新穩(wěn)定版的方法分享,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • 淺談express 中間件機(jī)制及實(shí)現(xiàn)原理

    淺談express 中間件機(jī)制及實(shí)現(xiàn)原理

    本篇文章主要介紹了淺談express 中間件機(jī)制及實(shí)現(xiàn)原理,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08

最新評(píng)論