相关文章
基于阿里egg框架搭建博客(1)——开发准备
基于阿里egg框架搭建博客(2)——Hello World
基于阿里egg框架搭建博客(3)——注册与登录
基于阿里egg框架搭建博客(4)——权限控制
基于阿里egg框架搭建博客(5)——置顶导航条
基于阿里egg框架搭建博客(6)——浏览、发表文章
基于阿里egg框架搭建博客(7)——编辑文章
git
https://github.com/ZzzSimon/e...
喜欢就点个赞吧!
正文
俗话说万事开头难,此章节涉及大量的知识点,在每个代码后面都有解释,需要大家查看官方文档。
user表设计
简单来说,注册与登录就是对user表的读写。所以我们首先对user表进行设计:
字段说明
字段 | 解释 |
---|---|
id | uuid |
username | 用户名 |
password | 密码 |
phone | 手机号 |
create_time | 创建时间 |
update_time | 更新时间 |
avatar_url | 头像url |
sql脚本
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` varchar(20) NOT NULL,
`username` varchar(18) NOT NULL,
`password` varchar(20) NOT NULL,
`phone` varchar(11) DEFAULT NULL,
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
`avatar_url` varchar(255) DEFAULT NULL,
PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
注册
页面设计
页面设计如上图所示,需要用户输入用户名,密码,手机号,还可以上传自己的头像。
前端代码
官方文档推荐我们使用nunjucks
作为模板。
使用方法: https://eggjs.org/zh-cn/intro...
我们在app\view\home
目录下创建register.tpl
文件:
注册
有3点需要注意:
- 静态文件的引用路径
/public
官方文档: https://eggjs.org/zh-cn/intro...
bootstrap自行搜索并下载,也可以用cdn。
- form表单请求url中的
?_csrf={{ ctx.csrf | safe }}
部分
官方文档: https://eggjs.org/zh-cn/core/...
- 最后一段js代码的作用:
由于bootstrap没有input type=file
标签样式,原版实在丑的不行,于是我把原版的隐藏了,在头像图片的点击事件监听里面,手动触发input type=file
文件上传按钮的click事件。
然后当用户选完头像后,通过window.FileReader
实时把图片显示出来。
后端代码
HomeController
我们在app\controller\
目录下创建home.js
文件:
该controller主要返回主页、登录页、注册页等基础页面。
const Controller = require('egg').Controller;
class HomeController extends Controller {
async register(){
await this.ctx.render('home/register.tpl')
}
}
module.exports = HomeController;
UserController
我们在app\controller\
目录下创建user.js
文件:
//app/controller/user.js
const Controller = require('egg').Controller;
const fs = require('mz/fs');
class UserController extends Controller{
async register(){
const ctx = this.ctx;
const { username, password, phone } = ctx.request.body;
const avatar = ctx.request.files[0];
//默认头像
let filepathNew = this.config.baseDir+'\\app\\public\\avatar\\default.jpg';
//如果用户上传了头像
if (avatar) {
console.log('file:%j', avatar);
let filenameNew = ctx.helper.uuid() +'.'+ avatar.filename.split('.').pop();
filepathNew = this.config.baseDir+'\\app\\public\\avatar\\'+filenameNew;
//把临时文件剪切到新目录去
await fs.rename(avatar.filepath, filepathNew);
}
const nowTime = new Date();
const userNew = {
id : ctx.helper.uuid(),
username : username,
password : password,
phone : phone,
avatar_url : filepathNew.split("\\app")[1],
create_time : nowTime,
update_time : nowTime
};
const flag = await ctx.service.user.save(userNew);
if (flag){
// 设置 Session
ctx.session.user = {username:username};
ctx.cookies.set('avatarUrl',userNew.avatar_url,{httpOnly:false});
ctx.body = {
successFlag:'Y',
errorMsg:'登录成功!'
};
ctx.redirect('/')
}else {
ctx.body = {
successFlag:'N',
errorMsg:'用户名已存在!'
}
}
}
}
module.exports = UserController;
有4点需要注意:
- controller获取上传的文件
官方文档: https://eggjs.org/zh-cn/basic...
- cookie与session
官方文档: https://eggjs.org/zh-cn/core/...
- 重定向
官方文档: https://eggjs.org/zh-cn/basic...
- uuid工具类,helper的使用
官方文档: https://eggjs.org/zh-cn/basic...
附上我自己实现的uuid生成方法:
moment组件请自行npm安装,官方: http://momentjs.cn/
const moment = require('moment');
//uuid格式:年月日时分秒3位毫秒+3位随机数,共20位 ===> 20190312162455043167
exports.uuid = function uuid() {
let uuid = moment().format("YYYYMMDDHHmmssSSS");
uuid += (Array(3).join(0) + Math.random()*100).slice(-3);
return uuid;
};
UserService
我们在app\service\
目录下创建user.js
文件:
const Service = require('egg').Service;
class UserService extends Service {
async save(user){
const userQ =await this.app.mysql.get('user', {username : user.username});
if (userQ){
return false
}else {
const result =await this.app.mysql.insert('user', user);
// 判断插入成功
const insertSuccess = result.affectedRows === 1;
if (insertSuccess) {
return true
}
}
return false
}
}
module.exports = UserService;
有1点需要注意:
- mysql的使用
官方文档: https://eggjs.org/zh-cn/tutor...
router.js
我们在app\
目录下的router.js
文件中添加以下内容:
module.exports = app => {
const { router, controller } = app;
//页面
router.get('/register.htm', controller.home.register);
//接口
router.post('/user/register',controller.user.register);
};
登录
页面设计
前端代码
我们在app\view\home
目录下创建login.tpl
文件:
登录
后端代码
HomeController
我们在app\controller\home.js
文件中添加以下内容:
async login(){
await this.ctx.render('home/login.tpl');
}
UserController
我们在app\controller\user.js
文件中添加以下内容:
async login(){
const ctx = this.ctx;
ctx.logger.info('req body:: %j',ctx.request.body);
const { username, password, rememberMe } = ctx.request.body;
const user = await ctx.service.user.loginAndGetUser(username, password);
if (!user){
ctx.body = {
successFlag:'N',
errorMsg:'用户名或密码错误!'
}
}else {
// 设置 Session
ctx.session.user = {username:user.username};
ctx.cookies.set('avatarUrl',user.avatar_url,{httpOnly:false});
// 如果用户勾选了 `记住我`,设置 的过期时间
if (rememberMe) ctx.session.maxAge = this.config.rememberMe;
ctx.body = {
successFlag:'Y',
errorMsg:'登录成功!'
};
ctx.redirect('/')
}
}
有1点需要注意:
- 用户勾选'记住我'后的session过期时间读取了配置文件中的值。配置:
官方文档: https://eggjs.org/zh-cn/basic...
UserService
我们在app\service\user.js
文件中添加以下内容:
async loginAndGetUser(username, password) {
const user =await this.app.mysql.get('user', {username : username});
if (!user || user.password !== password){
return false
} else {
return user;
}
}
router.js
我们在app\router.js
文件中添加以下内容:
router.get('/login.htm',controller.home.login);
router.post('/user/login',controller.user.login);
配置文件参考
config.default.js
参考官方文档后,你的配置文件应该如下(object 对象写法):
const path = require('path');
module.exports = appInfo => {
return {
keys: "123456",
rememberMe : 24 * 60 * 60 * 1000, //选择记住我之后,session有效时长
security : {
domainWhiteList:['.127.0.0.1'], // 安全白名单,以 . 开头
},
multipart : {
mode: 'file',
tmpdir: path.join(appInfo.baseDir, 'app/public/temp'),
},
session : {
key: 'EGG_SESS',
maxAge: 10 * 1000, // 单位毫秒
httpOnly: true,
encrypt: true,
},
view : {
defaultViewEngine: 'nunjucks',
mapping: {
'.tpl': 'nunjucks',
},
},
mysql : {
// 单数据库信息配置
client: {
// host
host: 'localhost',
// 端口号
port: '3306',
// 用户名
user: '数据库账号',
// 密码
password: '数据库密码',
// 数据库名
database: '你的数据库名',
},
// 是否加载到 app 上,默认开启
app: true,
// 是否加载到 agent 上,默认关闭
agent: false,
},
};
};
plugin.js
exports.nunjucks = {
enable: true,
package: 'egg-view-nunjucks'
};
exports.mysql = {
enable: true,
package: 'egg-mysql',
};
结尾
如果看完觉得有用,请给作者一个喜欢吧!谢谢啦!