開發與維運

使用node+express+mongodb實現用戶註冊、登錄和驗證功能


無論是手機端還是pc端,幾乎都包含登錄註冊方面功能,今天就使用node+express+mongodb實現一套登錄註冊功能,這裡需要自己去安裝MongoDB環境,如果沒有安裝可以看這篇關於MongoDB安裝的步MongoDB安裝配置教程 - 小周sri的碼農 - 博客園

 

實現功能
註冊 密碼加密
登錄 校驗 token處理
1.環境搭建運行
在目錄裡安裝express和mongoose,並在根目錄創建server.js文件和models文件,

在server.js文件中

const express = require('express');
const app = express();

app.listen(3001,() =>{

console.log('http://localhost:3001')

})
在你models文件中鏈接MongoDB數據庫,express-auth這個就是你數據庫的名字,27017是你數據庫的端口號,mongodb不需要打開數據庫可視化工具,根據名字就自動創建這個數據庫名了

const mongoose = require('mongoose')
// 鏈接數據庫
mongoose.connect('mongodb://localhost:27017/express-auth',{

useCreateIndex:true,
useNewUrlParser:true

})
在你server.js寫一點路由,測試數據庫是否鏈接成功,啟動服務的話,你可以全局安裝nodemon ,然後通過在命令控制檯出入nodemon server.js就可以,會實時更新我們修改的代碼,

app.get('/api/test',async(req,res) =>{

res.send('ok')

})
在這裡我們可以在Vcode中安裝一個REST Client插件,可以不需要postman就可以調試接口,也是在你的根目錄創建一個http結尾的目錄。url就是我們的訪問域名,定義一個全局的,get就是請求方式,後面test就是請求名。在右邊就可以看到我們返回的結果。要在server.js目錄引入才能生效。

註冊功能
首先建立模型,在models.js建立對應的模型,這裡因為是登錄和註冊,就寫兩個字段就行,如果需要,可以自行添加對應的字段名,unique表示用戶名是唯一的,不讓重複添加

const UserSchema = new mongoose.Schema({

username:{
    type:String,
    unique:true //字段是否唯一
},
password:{
    type:String
}

})

const User = mongoose.model('User',UserSchema)
module.exports = {User}
在你server.js文件,先引入這個模型

const {User} = require('./models')
編寫接口,create是mongoose語法,創建

// 註冊
app.post('/api/register',async(req,res) =>{

const user = await User.create({
    username:req.body.username,
    password:req.body.password
})
// 返回出去
res.send(user)

})
然後在test.http文件測試,可以看出來返回的結果是我們填寫的用戶名和密碼,但是這樣密碼暴露了,對用戶信息造成安全隱私問題。應該是用戶填寫密碼,保存數據庫的時候,應該是一段亂文,服務端看不懂的一段密碼。這裡就需要用到對密碼加密處理,以前經常用的是md5,現在最常用的是bcryptjs加密方式。

 安裝加密bcryptjs依賴包,這個和bcrypt原理是一樣的,如果第bcrypt安裝不成功,就是要bcryptjs安裝就行,用法 一樣的

cnpm install bcryptjs --save
然後直接對模型進行修改就行,直接在password添加set,對返回值進行處理就行,通過bcryptjs中的hashSync生成hash密碼

const UserSchema = new mongoose.Schema({

username:{
    type:String,
    unique:true //字段是否唯一
},
password:{
    type:String,
    set(val){
        // 通過bcryptjs對密碼加密返回值 第一個值返回值, 第二個密碼強度
        return require('bcryptjs').hashSync(val,10)
    }
}

})
 再次測試,因為是post請求,需要添加Content-Type: application/json,所有全局定義一個@json,然後只要是post請求的就直接tongg{{json}}使用

上面這種返回密碼格式,就是我們需要的格式,保障用戶密碼的安全性

登錄功能
登錄和註冊用的字段一樣的。所以不需要建立模型編寫,登錄時候,第一步肯定先判斷用戶是不是存在,如果用戶不存在,直接返回狀態碼和錯誤信息,也不需要執行下一步,第二步用戶名過了,接來下就是驗證密碼是否正確,通過compareSync驗證面密碼是否正確,如果正確就返回,不正確的話也是返回狀態碼和錯誤信息,最後一步就是生成token,返回客戶端,客戶端可以通過token判斷是哪個用戶。SECRET定義的是一個祕鑰,先隨便填寫,這個祕鑰應該不要出現在代碼中,

const SECRET = 'ewgfvwergvwsgw5454gsrgvsvsd'
安裝 jsonwebtoken依賴包 並引入

const jwt = require('jsonwebtoken')
 像下面這些判斷用戶存在或者密碼不正確,沒有寫好幾行代碼才能解決,推薦安裝一個插件http-assert錯誤提示

const assert = require('http-assert')
引入之後,就可以使用了(本次案例中沒有使用,其他項目中使用了,測試沒有任何問題,放心使用)

assert(user, 422, '用戶不存在') 這個就相當於下面這麼多行代碼了,簡潔明瞭

if(!user) {

    return res.status(422).send({
        message:"用戶不存在"
    })
}

app.post('/api/login',async(req,res) =>{

const user = await User.findOne({
    username:req.body.username
})
if(!user) {
    return res.status(422).send({
        message:"用戶不存在"
    })
}

const isPasswordValid = require('bcryptjs').compareSync(
    req.body.password,
    user.password
)
if(!isPasswordValid){
    return res.status(422).send({
        message:"密碼無效"
    })
}


const token = jwt.sign({
    id:String(user._id)
},SECRET)

// 生成token
res.send({
    user,
    token
})

})
 上面就可以實現登錄成功之後返回token,這個token裡面包含用戶的一個id.

 token校驗
token校驗,驗證比如獲取用戶信息,發送什麼東西的時候,判斷token是否存在,如果存在可以執行,否則不能執行,全局寫一箇中間件,當每個接口使用的時候,直接調用就可以

const auth = async(req,res) =>{

const raw = String(req.headers.authorization).split(' ').pop();
// 驗證
const {id} = jwt.verify(raw,SECRET)
req.user = await User.findById(id)

}
 例如:請求用戶列表,需要傳token驗證是否存在。auth就是驗證這個token是否存在。

app.get('/api/profile',auth,async(req,res) =>{

res.send(req.user)

})
 最終所有的代碼已提交到github中,有需要的可以下載看看GitHub - MrZHLF/node-express-mongodb: 使用node實現登錄註冊驗證功能

Leave a Reply

Your email address will not be published. Required fields are marked *