• 使用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

  • 相关阅读:
    oracle(八)块清除
    oracle(七)索引
    oracle(六) physical read and logical read
    oracle动态视图(一)stat
    oracle(五)tkprof 使用 transient kernal profile 侧面 轮廓
    dbms_stats.gather_table_stats详解
    oracle(四) 常用语句
    oracle(三) SQL语句
    [Swift]LeetCode269. 外星人词典 $ Alien Dictionary
    [Mac]如何让两个窗口各占半个屏幕
  • 原文地址:https://www.cnblogs.com/zhoulifeng/p/11804366.html
Copyright © 2020-2023  润新知