使用node+express+mongodb实现用户注册、登录和验证功能

无论是手机端还是pc端,几乎都包含登录注册方面功能,今天就使用node+express+mongodb实现一套登录注册功能,这里需要自己去安装MongoDB环境,如果没有安装可以看这篇关于MongoDB安装的步https://www.cnblogs.com/zhoulifeng/p/9429597.html

实现功能

  • 注册 密码加密
  • 登录 校验 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中,有需要的可以下载看看https://github.com/MrZHLF/node-express-mongodb

 

posted @ 2019-11-06 14:38  小周sri的码农  阅读(2995)  评论(0编辑  收藏  举报