node+express+mongoose构建项目

步骤:

        1.node安装

        2.npm init  初始化项目

        3.安装项目使用到的node框架

npm install express

let express = require('express');
let app = new express();

/* 
    为了满足正式环境中的node服务的端口启动需求,有时候需要用到port环境变量,那么这时候就需要在node启动时,设置process.env.PORT
 */
const port = process.env.PORT || 5000;

// 拦截get请求
app.get('/', (req, res) => {
    /* 
        res.send('响应内容');服务器端有数据返回到客户端
        res.end();终结响应处理流程
        
    res.end() 只接受服务器响应数据,如果是中文则会乱码
    res.send() 发送给服务端时,会自动发送更多的响应报文头,其中包括 Content-Tpye: text/html; charset=uft-8,所以中文不会乱码
    */
    res.send('你好!express')
})



// 错误中间件(要放在最后面)
app.use((err, req, res, next) => {
    res.send("Error!" + err.message);
})


// 监听启动服务器
app.listen(port, () => {
    console.log(`Server running http://localhost:${port}`)
});

配置启动js的命令:

    并在package.json文件scripts属性下配置cdm命令(启动node server.js)
        "start": "node server.js/项目入口js",
    dm命令行中输入:npm run start 启动项目

浏览器上输入:

        4.全局安装node热加载(实时监听js文件的改动 更新)

npm install nodemon -g

    并在package.json文件scripts属性下配置cdm命令(热启动node server.js)
        "server": "nodemon server.js/项目入口js"
    cdm命令行中输入:npm run server 启动

         5.操作数据库

         5.1安装mongodb数据库

npm install mongoose

                5.1.1 Mongoose 是一个让我们可以通过Node来操作MongoDB数据库的一个模块
                5.1.2 Mongoose 是一个对象文档模型(ODM)库,它是对Node原生的MongoDB模块进行了进一步的优化封装
                5.1.3 大多数情况下,他被用来把结构化的模式应用到一个MongoDB集合,并提供了验证和类型装换等好处
                5.1.4 基于MongoDB驱动,通过关系型数据库的思想来实现非关系型数据库。

          5.2安装数据库可视化工具MongoDB Compass Community

        6.通过Node来操作MongoDB数据库的一个模块(mongoose)

测试:

 /config/keys.js(配置url文件)

module.exports = {
    mongoURL: "mongodb://127.0.0.1:27017"
}
let express = require('express');
let app = new express();
let mongoose = require('mongoose');

/* 
    为了满足正式环境中的node服务的端口启动需求,有时候需要用到port环境变量,那么这时候就需要在node启动时,设置process.env.PORT
 */
const port = process.env.PORT || 5000;


// DB config
const db = require('./config/keys').mongoURL;
// Connect to mongodb
mongoose.connect(db)
    .then(() => console.log('MongoDB Connected Success'))
    .catch((err) => console.log(err))


// 拦截get请求
app.get('/', (req, res) => {
    /* 
        res.send('响应内容');服务器端有数据返回到客户端
        res.end();终结响应处理流程
        
    res.end() 只接受服务器响应数据,如果是中文则会乱码
    res.send() 发送给服务端时,会自动发送更多的响应报文头,其中包括 Content-Tpye: text/html; charset=uft-8,所以中文不会乱码
    */
    res.send('你好!express')
})


// 错误中间件(要放在最后面)
app.use((err, req, res, next) => {
    res.send("Error!" + err.message);
})

// 监听启动服务器
app.listen(port, () => {
    console.log(`Server running http://localhost:${port}`)
});

6.2 开发测试接口

express----路由的使用 

/routes/api/users.js

const express = require('express');
const router = express.Router();

/* 
$route GET api/users/test
@desc  返回请求的json数据
@access public
 */
router.get('/test', (req, res) => {
    res.json({ msg: "login works" })
})


module.exports = router;

 在server.js入口文件中引入api接口

// 引入users.js
const users = require('./routes/api/users');
// 中间件使用routes
app.use('/api/users', users)

 

获取post表单的中间件body-parser

npm install body-parser

 注意:配置要放在接口之前

body-parser 中间件 第三方的 获取 post 提交的数据
1.npm install body-parser --save
2.const bodyParser = require('body-parser')
3.设置中间件(注意这里要放到路由/api中间件前面)
//处理 form 表单的中间件
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false })); form 表单提交的数据
// parse application/json
app.use(bodyParser.json()); 接受json 类型的数据
4.req.body 获取数据
/* 
    server.js入口文件
    使用body-parser中间件
    此部分要放在路由中间件前面
*/
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

密码加密bcrypt (哪个api需要在哪个文件引入)

npm install bcrypt 

const bcrypt = require('bcrypt');

//saltRounds:生成盐,参数为加密的强度(0~99),默认为10,值越高强度越大,但是解密验证的时候性能越低。
bcrypt.genSalt(saltRounds = 10, function (err, salt) {
    bcrypt.hash(newUser.password, salt, function (err, hash) {  // 需要加密
        if (err) throw err;
            newUser.password = hash;
            // 保存文档(mongoose提供)
            newUser.save()
                   .then(user => res.json(user))
                   .catch(err => console.log)
      });
});

 实战:实现注册页api

数据库的字段:/models/User.js

// 操作数据库字段配置
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// Create Schema(创建字段)
const UserSchema = new Schema({
    name: {
        type: String,
        required: true
    },
    email: {
        type: String,
        required: true
    },
    avatar: {
        type: String
    },
    password: {
        type: String,
        required: true
    },
    date: {
        type: Date,
        default:Date.now(), //返回创建时间戳
    },
})

/* 
    Model 代表的是数据库中的集合,通过Model才能对数据库进行操作
    第一个参数要映射的集合名;第二个创建的约束(Schema对象)
*/
module.exports = User = mongoose.model('users',UserSchema);

api接口实现:/routes/api/user.js

const express = require('express');
const router = express.Router();
const bcrypt = require('bcrypt');

const User = require('../../models/User');  // 操作数据库字段配置

/* 
$route GET api/users/test
@desc  返回请求的json数据
@access public
 */
router.get('/test', (req, res) => {
    res.json({ msg: "login works" })
})

/* 
$route POST api/users/register
@desc  返回请求的json数据
@access public
 */
router.post('/register', (req, res) => {
    console.log(req.body)
    // 查询数据库中是否有这个人
    User.findOne({ email: req.body.email })
        .then((user) => {
            if (user) {
                return res.status(400).json({ name: "用户已被注册!" });
            } else {
                // return res.json('用户注册中...')
                const newUser = new User({
                    name: req.body.name,
                    email: req.body.email,
                    password: req.body.password
                });
                //saltRounds:生成盐,参数为加密的强度(0~99),默认为10,值越高强度越大,但是解密验证的时候性能越低。
                bcrypt.genSalt(saltRounds = 10, function (err, salt) {
                    bcrypt.hash(newUser.password, salt, function (err, hash) {  // 需要加密
                        if (err) throw err;
                        newUser.password = hash;
                        // 保存文档(mongoose提供)
                        newUser.save()
                            .then(user => res.json(user))
                            .catch(err => console.log)
                    });
                });
            }
        })
})



module.exports = router;

 加密补充知识:

            /* 
                生成加密
                bcrypt.genSalt() 加密
                saltRounds:生成盐,参数为加密的强度(0~99),默认为10,值越高强度越大,但是解密验证的时候性能越低。
            */
            bcrypt.genSalt(saltRounds = 10, function(err, salt) {
                bcrypt.hash(req.body.password, salt, function(err, hash) {
                    if (err) throw err;
                    newUser.password = hash;
                    // 保存文档(mongoose提供)
                    newUser.save()
                        .then(user => res.json(user))
                        .catch(err => console.log(err))
                });
            });
/*
    解析加密的字段
*/
bcrypt.compare(当前密码, 存储密码, function(err, result) {
    
}

server.js入口

let express = require('express');
let mongoose = require('mongoose');
let bodyParser = require('body-parser'); // 解析请求体

/* 
    为了满足正式环境中的node服务的端口启动需求,有时候需要用到port环境变量,那么这时候就需要在node启动时,设置process.env.PORT
 */
const port = process.env.PORT || 5000;

let app = new express();

// DB config
const db = require('./config/keys').mongoURL;
// Connect to mongodb
mongoose.connect(db)
    .then(() => console.log('success'))
    .catch((err) => console.log(err))


/* 
    使用body-parser中间件
    此部分要放在路由中间件前面
*/
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// 引入users.js
const users = require('./routes/api/users');
// 中间件使用routes
app.use('/api/users', users)


// 拦截get请求
app.get('/', (req, res) => {
    /* 
        res.send('响应内容');服务器端有数据返回到客户端
        res.end();终结响应处理流程
        
    res.end() 只接受服务器响应数据,如果是中文则会乱码
    res.send() 发送给服务端时,会自动发送更多的响应报文头,其中包括 Content-Tpye: text/html; charset=uft-8,所以中文不会乱码
    */
    res.send('你好!express')
})


// 错误中间件(要放在最后面)
app.use((err, req, res, next) => {
    res.send("Error!" + err.message);
})

// 监听启动服务器
app.listen(port, () => {
    console.log(`Server running http://localhost:${port}`)
});

 7.安装postman软件测试api

在MongoDB Compass Community可视化工具上查看是否添加成功:

全球公认头像的使用:(辅助)

npm install gravatar

        /* 
         http://www.gravatar.com/avatar/参数1?s=参数2&d=参数3&r=参数4

         参数1:在Gravatar网站上注册的邮箱的MD5值
         参数2:指的是图片的大小,自定义参数,整数
         参数3:如果为identicon,随机显示图纹图片,默认显示蓝底白字G图片
         参数4:图片类型。(G 普通级、PG 辅导级、R 和 X 为限制级),不过一般情况下都是G 
             gravatar.url(邮箱,{图片大小,图片类型,默认})
         */
         let avatar = gravatar.url(req.body.email, { s: '200', r: 'pg', d: 'mm' });

api接口实现:/routes/api/user.js

const gravatar = require('gravatar'); // 公共头像



/* 
$route POST api/users/register
@desc  返回请求的json数据
@access public
 */
router.post('/register', (req, res) => {
    // 查询数据库中是否存在这个人
    let { email } = req.body;
    User.findOne({ email }).then(user => {
        if (user) {
            return res.status(404).json('用户已注册')
        } else {
            /* 
             http://www.gravatar.com/avatar/参数1?s=参数2&d=参数3&r=参数4

                参数1:在Gravatar网站上注册的邮箱的MD5值
                参数2:指的是图片的大小,自定义参数,整数
                参数3:如果为identicon,随机显示图纹图片,默认显示蓝底白字G图片
                参数4:图片类型。(G 普通级、PG 辅导级、R 和 X 为限制级),不过一般情况下都是G 
            gravatar.url(邮箱,{图片大小,图片类型,默认})
             */
            let avatar = gravatar.url(req.body.email, { s: '200', r: 'pg', d: 'mm' });
            const newUser = new User({
                name: req.body.name,
                email: req.body.email,
                password: req.body.password,
                avatar,
                identity: req.body.identity,
            })

            /* 
                bcrypt.genSalt() 加密
                saltRounds:生成盐,参数为加密的强度(0~99),默认为10,值越高强度越大,但是解密验证的时候性能越低。
            */
            bcrypt.genSalt(saltRounds = 10, function(err, salt) {
                bcrypt.hash(req.body.password, salt, function(err, hash) {
                    if (err) throw err;
                    newUser.password = hash;
                    // 保存文档(mongoose提供)
                    newUser.save()
                        .then(user => res.json(user))
                        .catch(err => console.log(err))
                });
            });
        }
    }).catch(err => {
        if (err) throw err;
    })
})

 8. 开发登录接口

登录token(token相当于是一个识别令牌,只有拿到这个令牌才能获取到其他的信息),相当于是一个权限

    生成token

        npm install jsonwebtoken

   验证token

        npm install passport

        npm install passport-jwt

/routes/api/user.js

const jwt = require('jsonwebtoken'); // 生成 JWT 字符串(token)
const keys = require('../../config/keys'); // 
const passport = require('passport'); // 验证token



/* 
$route  POST api/users/login
@desc   返回token jwt passport
@access public
 */
router.post('/login', (req, res) => {
    const { email, password } = req.body;
    // 查询数据库
    User.findOne({ email }).then(user => {
        if (!user) {
            return res.status(404).json("用户不存在!请注册用户")
        }
        // 密码匹配
        bcrypt.compare(password, user.password, (err, result) => {
            // console.log(password, user.password, result);
            if (result) {
                /* 
                jwt.sign(规则, token密钥,过期时间, 箭头函数)
                返回token
                 */
                const rule = {
                    id: user.id,
                    name: user.name,
                    avatar: user.avatar,
                    identity: user.identity
                }
                let token = jwt.sign(rule, keys.secretOrKey, { expiresIn: 60 * 60 * 1000 }, (err, token) => {
                    if (err) {
                        throw err;
                    } else {
                        // "Bearer "固定
                        res.json({
                            success: true,
                            token: "Bearer " + token
                        })
                    }
                })
            } else {
                return res.status(400).json('密码错误!')
            }
        })
    })
})

生成token说明

                /* 
                jwt.sign(规则, token密钥,过期时间, 箭头函数)
                返回token
                 */
                const rule = {
                    id: user.id,
                    name: user.name,
                    avatar: user.avatar,
                    identity: user.identity
                }
                let token = jwt.sign(rule, keys.secretOrKey, { expiresIn: 60 * 60 * 1000 }, (err, token) => {
                    if (err) {
                        throw err;
                    } else {
                        // "Bearer "固定
                        res.json({
                            success: true,
                            token: "Bearer " + token
                        })
                    }
                })

/config/keys.js

module.exports = {
    mongoURL: "mongodb://127.0.0.1:27017",
    secretOrKey: "secret", // token 密钥配置
}

在postman进行测试:

9. 开发携带 token 请求头信息,获取用户信息

server.js 配置解析token的中间件

const passport = require('passport'); // 验证token


// passport初始化(验证token,解析 token,路由前)
app.use(passport.initialize());
require('./config/passport')(passport);

/routes/api/user.js

/* 
$route  GET api/users/current
@desc   返回当前用户(测试携带 token 获取当前的用户)
@access private

需在headers带上token验证
passport.authenticate(验证方式)
    禁用会话 Disable Sessions
 */
router.get('/current', passport.authenticate('jwt', { session: false }), (req, res) => {
    // res.json({msg: "current success"});
    // 返回用户信息
    res.json({
        id: req.user.id,
        name: req.user.name,
        email: req.user.email,
        identity: req.user.identity
    });
})

在postman进行测试:

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值