gtihub仓库地址:(由于国内处于敏感时期,github暂时无法访问)

主要使用的中间件:

"ejs": "^2.7.1",(渲染模板)
"koa": "^2.8.1",(主角)
"koa-bodyparser": "^4.2.1",(用于获取post提交的数据)
"koa-router": "^7.4.0",(koa2路由控制)
"koa-session": "^5.12.3",(用于权限认证)
"koa-static": "^5.0.0",(用于加载静态资源)
"koa-views": "^6.2.1",(配合ejs使用)
"mongodb": "^3.3.2"(数据库)

项目目录结构:

*   app.js            //主入口文件
* package.json //项目相关信息
* README.md
*
****module //封装好的数据库操作模块
* config.js //数据库配置信息
* db.js //数据库增删改查
*
****views //模板文件夹
* index.ejs //首页
* login.ejs //登录页面
* register.ejs //注册页面
*
****public //公共渲染页面模块
* footer.ejs//footer页面
*
****statics //静态资源目录
* basic.css
* form.css

项目分析:

废话不多说,直接上代码!!!

app.js

const Koa=require('koa');//引入koa
const router=require('koa-router')();//引入koa-router
const views=require('koa-views');//引入koa-views
const bodyParser=require('koa-bodyparser');//引入koa-bodyparser
const static=require('koa-static');//引入koa-static
const session = require('koa-session');//引入koa-session
const DB=require('./module/db.js');//引入数据库操作模块 const app=new Koa();//初始化koa app.use(views('views', { extension: 'ejs' }))//配置koa-views
app.use(bodyParser());//配置koa-bodyparser
app.use(static(__dirname+'/views'));//配置koa-static静态资源目录 app.keys = ['some secret hurr']; /*cookie的签名*/
const CONFIG = {
key: 'koa:sess', /** 默认 */
maxAge: 10000, /* cookie的过期时间 【需要修改】 */
overwrite: true, /** (boolean) can overwrite or not (default true) 没有效果,默认 */
httpOnly: true, /** true表示只有服务器端可以获取cookie */
signed: true, /** 默认 签名 */
rolling: false, /** 在每次请求时强行设置 cookie,这将重置 cookie 过期时间(默认:false) 【需要修改】 */
renew: false, /** (boolean) renew session when session is nearly expired 【需要修改】*/
};
app.use(session(CONFIG, app));//配置koa-session //写一个中间件配置公共的信息
app.use(async (ctx,next)=>{ ctx.state.title='koa2登陆注册权限练习';//ctx.state可以在全局获取到
ctx.state.name=ctx.session.name; await next();/*继续向下匹配路由*/
}) //首页
router.get('/',async (ctx,next)=>{ // ctx.body='这是主页面';
// ctx.session.name='张文浩'; var result=await DB.find('users',{}); // console.log(result); await ctx.render('index.ejs',{
list:result
});
await next();
}) //登陆页面
router.get('/login',async (ctx,next)=>{
// ctx.body='这是登陆面'; await ctx.render('login.ejs'); }) router.post('/dologin',async (ctx)=>{
// ctx.body='这是登陆面';
// console.log(ctx.request.body); // ctx.body=ctx.request.body;
let data=await DB.find('users',ctx.request.body);
// console.log(data[0]);
try{
if(data[0]){ ctx.session.name=data[0].name;
ctx.redirect('/'); }
else{
ctx.redirect('/');
}
}catch(err){
console.log(err);
return;
ctx.redirect('/login');
} }) //注册页面
router.get('/register',async (ctx,next)=>{
// ctx.body='这是注册面';
// console.log(ctx.session.name); await ctx.render('register.ejs'); }) router.post('/doregister',async (ctx)=>{
// ctx.body='这是注册面'; // console.log(ctx.request.body);
// ctx.body=ctx.request.body;s
let data=await DB.insert('users',ctx.request.body);
//console.log(data);
try{
if(data.result.ok){
ctx.redirect('/')
}
}catch(err){
console.log(err);
return;
ctx.redirect('/register');
}
}) //删除操作
router.get('/delete',async (ctx)=>{ if(ctx.session.name){
let id=ctx.query.id;
// console.log(ctx.query.id);
var data=await DB.remove('users',{"_id":DB.getObjectId(id)});
// console.log(data);
if(data){
ctx.redirect('/')
}
}
else{
ctx.redirect('/')
} }) app.use(router.routes()).use(router.allowedMethods());//启动路由
app.listen(3001,()=>{
console.log('已经在3001端口运行!');
})

views下主要的渲染页面

使用了ejs渲染引擎<% %>为其语法
/*index页面*/
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="statics/basic.css"/>
</head>
<body>
<% if(name){%>
<h2>欢迎,<%= name%></h2>
<% }else{ %>
<h2><a href="/login">登陆</a><a href="/register">注册</a></h2>
<% } %>
<hr/>
<table>
<% for(var i=0;i<list.length;i++){%>
<tr>
<td><%= list[i]._id%></td>
<td><%= list[i].name%></td>
<td><%= list[i].sex%></td>
<td><%= list[i].age%></td>
<td><a href="/delete?id=<%= list[i]._id%>">删除</a></td>
</tr> <%}%>
</table> <% include public/footer.ejs%>
</body>
</html> /*login页面*/
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="statics/form.css"/>
</head>
<body>
<h2>登陆</h2>
<hr/>
<div>
<form action="/dologin" method="POST">
账号:<input type="text" name="account"/><br/>
密码:<input type="password" name="password"/><br/> <button type="submit">登陆</button> </form>
</div>
<% include public/footer.ejs%>
</body>
</html> /*register页面*/
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="statics/form.css"/>
</head>
<body>
<h2>注册</h2>
<hr/>
<div>
<form action="/doregister" method="POST">
账号:<input type="text" name="account"/><br/>
密码:<input type="password" name="password"/><br/>
姓名:<input type="text" name="name"/><br/>
性别:<input type="text" name="sex"/><br/>
年龄:<input type="text" name="age"/><br/>
<button type="submit">注册</button>
</form>
</div>
<% include public/footer.ejs%>
</body>
</html>

module下的数据库模块

config.js

var app={
dbUrl: 'mongodb://localhost:27017/',
dbName: 'koa'
}
module.exports=app;

db.js

/**
*官方文档
* http://mongodb.github.io/node-mongodb-native
* http://mongodb.github.io/node-mongodb-native/3.0/api/
*/
var MongoDB=require('mongodb');
var MongoClient =MongoDB.MongoClient;
const ObjectID = MongoDB.ObjectID; var Config=require('./config.js'); class Db{
static getInstance(){ /*单例*/
if(!Db.instance){
Db.instance=new Db();
}
return Db.instance;
} constructor(){ this.dbClient=''; /**/
this.connect(); /*连接数据库*/ } connect(){ /*连接数据库*/
let _that=this;
return new Promise((resolve,reject)=>{
if(!_that.dbClient){ /*触发连接请求*/
MongoClient.connect(Config.dbUrl,(err,client)=>{
if(err){
reject(err)
}else{
_that.dbClient=client.db(Config.dbName);
resolve(_that.dbClient)
}
})
}else{
resolve(_that.dbClient);
}
})
} find(collectionName,json){ return new Promise((resolve,reject)=>{ this.connect().then((db)=>{ var result=db.collection(collectionName).find(json); result.toArray(function(err,docs){ if(err){
reject(err);
return;
}
resolve(docs);
}) })
})
}
update(collectionName,json1,json2){
return new Promise((resolve,reject)=>{ this.connect().then((db)=>{ //db.user.update({},{$set:{}})
db.collection(collectionName).updateOne(json1,{
$set:json2
},(err,result)=>{
if(err){
reject(err);
}else{
resolve(result);
}
}) }) }) }
insert(collectionName,json){
return new Promise((resolve,reject)=>{
this.connect().then((db)=>{ db.collection(collectionName).insertOne(json,function(err,result){
if(err){
reject(err);
}else{ resolve(result);
}
}) })
})
} remove(collectionName,json){ return new Promise((resolve,reject)=>{
this.connect().then((db)=>{ db.collection(collectionName).removeOne(json,function(err,result){
if(err){
reject(err);
}else{ resolve(result);
}
}) })
})
}
getObjectId(id){ return new ObjectID(id);
}
} module.exports=Db.getInstance();

koa2实现登录注册功能(ejs+mongodb版)的更多相关文章

  1. vue koa2 mongodb 从零开始做个人博客(一) 登录注册功能前端部分

    0.效果演示 插入视频插不进来,就很烦.可以出门右拐去优酷看下(点我!). 1.准备工作 1.1前端框架 前端使用了基于vue.js的nuxt.js.为什么使用nuxt.js? 首先我做的是博客的项目 ...

  2. Java Spring+Mysql+Mybatis 实现用户登录注册功能

    前言: 最近在学习Java的编程,前辈让我写一个包含数据库和前端的用户登录功能,通过看博客等我先是写了一个最基础的servlet+jsp,再到后来开始用maven进行编程,最终的完成版是一个 Spri ...

  3. Node.js实现登录注册功能

    使用Node.js + Navicat for mysql实现的登录注册功能 数据库中存在有”user_id,user_name,password,user_img,user_number“字段,其中 ...

  4. SSM 实现登录注册功能

    1.上一篇SSM框架搭建好了之后就要开始写功能了,现在来写一个简单的登录注册功能 这几个包是自己手动创建的,然后往里面写代码 2.代码详情 package com.maike.controller; ...

  5. flask 开发用户登录注册功能

    flask 开发用户登录注册功能 flask开发过程议案需要四个模块:html页面模板.form表单.db数据库操作.app视图函数 1.主程序 # app.py # Auther: hhh5460 ...

  6. JavaWeb_(session和application)用户登录注册模板_进阶版

    用户登录注册模板_基础版 传送门 用户登录注册模板进阶版 添加了获得获得当前登录用户信息及存储登录人数 用户登录后,在首页.注册页.登录页显示登录用户信息和存储登录人数信息 目录结构 <%@pa ...

  7. JAVAEE_Servlet_20_登录注册功能

    实现登录注册功能 注册功能 import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import j ...

  8. vue koa2 mongodb 从零开始做个人博客(二) 登录注册功能后端部分

    0.效果演示 插入视频插不进来,就很烦.可以出门右拐去优酷看下(点我!). 1.后端搭建 1.1项目结构 首先看一下后端的server目录 挨个解释一下 首先dbs文件夹顾名思义,操作数据库的,mod ...

  9. 一个关于vue+mysql+express的全栈项目(三)------ 登录注册功能的实现(已经密码安全的设计)

    本系列文章,主要是一个前端的视角来实现一些后端的功能,所以不会讲太多的前端东西,主要是分享做这个项目学到的一些东西,,,,, 好了闲话不多说,我们开始搭建后端服务,这里我们采用node的express ...

随机推荐

  1. 编译Linux-2.6.23内核中遇见的错误

    编译linux-2.6.23 错误[1]: elf_x86_64: 没有那个文件或目录 原因是 gcc 4.6 不再支持 linker-style 架构.在 arch/x86/vdso/Makefil ...

  2. 43.和为S的连续正数序列

    题目描述:   小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数).没多 ...

  3. etcd注册服务

    etcd作为最简单(轻量,精简)的kv服务.etcd可以应用很多方面,但是它有一个特点,etcd只是基础,需要你自己实现功能.它不像其其它组件开箱即用,也正是如此,它足够简单精巧. 回到主题,etcd ...

  4. Ansible--06 ansible roles

    Ansible roles roles不管是Ansible还是saltstack,我在写一键部署的时候,都不可能把所有的步骤全部写入到一个'剧本'文件当中,我们肯定需要把不同的工作模块,拆分开来,解耦 ...

  5. find 文件查找

    目录 find文件查找 1.为什么要使用文件查找 2.根据文件名称查找-name 3.根据文件大小查找-size 4.根据文件类型查找-type f 5.根据文件时间查找-mtime 6.根据文件用户 ...

  6. jq的ajax请求更改为axios请求时零碎总结

    #老版切新版更改处----ajax 更改为 axios //ajax$.ajax({ type: 'POST', url: url, data: data, success: success, dat ...

  7. python3.x 匿名函数lambda_扩展sort

    #匿名函数lambda 参数: 表达式关键字 lambda 说明它是一个匿名函数,冒号 : 前面的变量是该匿名函数的参数,冒号后面是函数的返回值,注意这里不需使用 return 关键字. ambda只 ...

  8. java模式-----单例模式

    什么是单例设计模式? 单例模式,是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例.即一个类只有一个对象实例. 类结构 ...

  9. Delphi DBGrid 实现复选框

    1 在数据库对应的表中加入  bit 列验证是否被选中 然后dbgrid第一列的filedname是bit列 在DBgrid的onDrawColumnCell事件中写: procedure DBGri ...

  10. c++11 中的注意事项

    1. C++11标准中让类的析构函数默认也是noexcept(true)的. 但如果显式地为析构函数指定了noexcept,或者类的基类或成员有noexcept(false)的析构函数,析构函数就不会 ...