基於node的登入例子(node-koa-mongoose)

前言

這是一個基於node實現的一個簡單登入例子,對於剛上手node想進一步瞭解,前端頁面如何請求到服務層 -> 路由處理 -> 數據庫操做 -> 返回結果到頁面這整個過程的同窗比較有用。這個例子基於github上兩個項目(文末有連接),本身整理改寫,但願有須要的同窗能夠看到。html

項目源碼地址https://github.com/linwalker/...前端

技術棧

  • node 使用 Koa框架,node版本7.6以上能夠直接使用async/await;node

  • 使用mongoose來與Mongodb數據庫鏈接交互;react

  • 前端使用react與antd-design組件;webpack

  • webpack 打包構建git

環境準備與運行

  • node.js >= 7.6github

  • mongodb 安裝web

  • robomongo 安裝 (mongodb的可視化工具)mongodb

  • mongodb 新建名爲node-login的數據庫,並開啓;數據庫

  • npm install 安裝依賴

  • npm run build 代碼構建

  • node app 開啓服務,能夠訪問localhost:3003/home

項目目錄

node-login
    |-- components                   //頁面組件
        |-- LoginTab.js
        |-- RegisterTab.js
    |-- controller          //路由回調處理
        |-- user-info.js
    |-- models                 //用戶模型
        |-- user.js
    |-- pages                    //頁面js
        |-- home
            |-- home.js
            |-- index.js
        |-- main
    |-- routes                    //路由
    |-- static                    //靜態文件
    |-- tools                    //webpack構建文件
    |-- views                    //頁面模版
    |-- .babelrc
    |-- app.js                    //入口文件
    |-- config.js                //配置文件
    |-- package.json

具體介紹

入口文件 - app.js

const Koa = require('koa');
const...
const app = new Koa();

// 配置控制檯日誌中間件
app.use(convert(koaLogger()));

// 使用ctx.body解析中間件
app.use(bodyParser());

// 配置服務端模板渲染引擎中間件
app.use(views(path.join(__dirname, './view'), {
    extension: 'ejs'
}));

// 配置靜態資源加載中間件
app.use(convert(koaStatic(
    path.join(__dirname , './static')
)))

mongoose.Promise = global.Promise;
mongoose.connect(config.database);

// 初始化路由中間件
app.use(routers.routes()).use(routers.allowedMethods())

app.listen(3003);
console.log('The server is on prot 3003')

服務主要進行數據庫鏈接,路由處理,靜態文件配置和頁面模板渲染。

配置文件 - config.js

module.exports = {
    'secrect': 'linwalkernodelogindemo', //暫未用到,用於後期token驗證
    'database': 'mongodb://localhost:27017/node-login'//填寫本地 mongodb 鏈接地址
};

主要設置鏈接mongodb數據的鏈接地址

用戶模型 - user.js

定義登入註冊的用戶模型

const mongoose = require('mongoose');
const Schema = mongoose.Schema
const UserSchema = new Schema({
    username: {
        type: String,
        unique: true,
        require: true
    },
    password: {
        type: String,
        require: true
    },
    email: {
        type: String,
    }
});

module.exports = mongoose.model('User', UserSchema);

用戶模型主要三個數據,用戶名,密碼和郵箱。

路由

路由總入口/routes/index.js引入全部路由,使用koa-router中間件

const router = require('koa-router')();
const home = require('./home');
const main = require('./main');
const editor = require('./editor');

router.use('/home', home.routes(), home.allowedMethods());
router.use('/main', main.routes(), main.allowedMethods());
router.use('/editor', editor.routes(), editor.allowedMethods());

module.exports = router;

三個主路由爲/home,/main//editor,主要來看下/home

const router = require('koa-router')();
const userInfoController = require('./../controller/user-info');

const routers = router
    .get('/', async (ctx) => {
        const title = 'login home';
        await ctx.render('home', {
            title
        })
    })
    .post('/signup', userInfoController.signUp)
    .post('/signin', userInfoController.signIn)

module.exports = routers;

home.jsget請求返回home頁面,兩個post請求,分別是註冊和登入處理。咱們來看下登入請求處理user-info.js

const User = require('./../models/user');

module.exports = {
    async signUp (ctx) {
        ...
    },

    async signIn (ctx) {
        let result = {
            success: false,
            message: '用戶不存在'
        };
        //從請求體中得到參數
        const { username,  password } = ctx.request.body;
        //檢查數據庫中是否存在該用戶名
        await User.findOne({
            username
        }, (err, user) => {
            if (err) {
                throw err;
            }
            if (!user) {
                ctx.body = result;
            } else {
                //判斷密碼是否正確
                if (password === user.password) {
                    ctx.body = {success: true, message: '登入成功'}
                } else {
                    ctx.body = {success: false, message: '密碼錯誤'}
                }
            }
        })
    }
}

登入請求處理過程爲先檢查用戶名是否存在,在判斷密碼是否正確。在來看下頁面發起請求的地方

登入請求

class LoginTab extends React.Component {
    handleSubmit = async(e) => {
        e.preventDefault();
        let values = await this.getFormValues();
        if (values) {
            fetch('/home/signin', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json; charset=utf-8'
                },
                body: JSON.stringify(values)
            }).then(res => {
                res.json().then(res => {
                    Message.info(res.message);
                    if (res.success) {
                        location.href = '/main';
                    }
                })
            })
        }
    }
    getFormValues() {
        let self = this;
        return new Promise((resolve, reject) => {
            self.props.form.validateFields((err, values) => {
                if (!err) {
                    resolve( values );
                } else {
                    reject( false );
                }
            })
        })
    }
    render() {
        const { getFieldDecorator } = this.props.form;
        return (
            <div style={{ width: "280px", margin: "0 auto" }}>
                <Form onSubmit={this.handleSubmit}>
                              ...      
                </Form>
            </div>
        )
    }
}
export default Form.create()(LoginTab);

表單提交按鈕綁定handleSubmit事件,該事件先獲取表單提交數據,再發起/home/signin的post請求,根據請求結果的success值,來決定是否跳轉到成功頁面。這裏用到antd-design表單組件的相應屬性。

操做演示

演示用戶名不存在,密碼錯誤及成功登入。

登入.gif

總結

  • 使用了koa框架,主要是路由和ctx上下文的處理,沒用過的同窗能夠點擊koa2教程去看看,這是koa的一個入門教程寫的很不錯;

  • 使用了mongoose操做數據庫,栗子中涉及的不難,只是一個User模型,一個save保存數據和一個findOne查找,看下文檔就明白,或則看下這篇文章

  • 使用antd-design 組件

備註

這個例子主要參考了:
項目1
項目2

相關文章
相關標籤/搜索