专栏首页前端技术开发使用node+express+mongodb实现用户注册、登录和验证功能

使用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, '用户不存在') 这个就相当于下面这么多行代码了,简洁明了

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Vue2.0-token权限处理

    token一种身份的验证,在大多数网站中,登录的时候都会携带token,去访问其他页面,token就想当于一种令牌。可以判断用户是否登录状态。本次页面是通过El...

    小周sri的码农
  • 使用node和express+mongodb实现数据增删改功能

    2018即将过去,2019即将来临,前端技术不断在在更新,学的东西越来越多。我们只有不断的学习,才不能被淘汰。在前后端分离的一个时代,后端提供接口,前端调用接口...

    小周sri的码农
  • nginx服务器搭建以及配置

    在根目录也就是root这个目录创建了一个nginx文件,这里面都存放我们安装的nginx

    小周sri的码农
  • Leetcode-Easy 72. Edit Distance

    72. Edit Distance 描述: 求两个字符串的编辑距离 ? 思路: 动态规划 代码 class Solution: ...

    致Great
  • Leetcode Golang 7. Reverse Integer.go

    版权声明:原创勿转 https://blog.csdn.net/anakinsun/article/details/88867281

    anakinsun
  • 数据结构之动态规划问题

    数据结构中动态规划应该算得上是你避不开的一道槛了吧!其重要性不言而喻,今天就整理下学习笔记分享出来。希望对读者朋友也能有帮助,文章基本框架如下:

    小小詹同学
  • jquery + node 通过 CORS 实现跨域访问,支持cookie和自定义header

      跨域有多种方式,现在的情况看来还是CORS更适合一些,有很多优点,比如浏览器正式支持、支持post、可以控制跨域访问的网站等。

    用户1174620
  • 【leetcode刷题】T62-罗马数字转整数

    例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II ...

    木又AI帮
  • 413. 反转整数从低到高逐位处理

    将一个整数中的数字进行颠倒,当颠倒后的整数溢出时,返回 0 (标记为 32 位整数)。 样例

    和蔼的zhxing
  • Express4.x API (三):Response (译)

    Express4.x API 译文 系列文章 技术库更迭较快,很难使译文和官方的API保持同步,更何况更多的大神看英文和中文一样的流畅,不会花时间去翻译--,所...

    okaychen

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动