On this page
登录功能
配置:config/config.default.js
js
config.session = {
// 在有些场景下,我们希望用户如果长时间都在访问我们的站点,则延长他们的 Session 有效期,不让用户退出登录态
renew: true,
// key 代表了存储 Session 的 Cookie 键值对的 key 是什么
key: "EGG_SESS",
// 最长保存时间(毫秒)
maxAge: 24 * 3600 * 1000 * 30, // 30 天
// 设置键值对是否可以被 js 访问,默认为 true,不允许被 js 访问。
httpOnly: true,
// 加密
encrypt: true,
};
控制器:app/controller/admin/home.js
js
// 引入crypto
const crypto = require('crypto');
// 登录页
async login() {
const { ctx } = this;
let toast = ctx.cookies.get('toast',{ encrypt: true });
toast = toast ? JSON.parse(toast) : null
await ctx.render('admin/home/login.html',{
toast
});
}
// 登录逻辑
async loginevent() {
const { ctx, app } = this;
// 参数验证
ctx.validate({
username: {
type: 'string',
required: true,
desc: '用户名'
},
password: {
type: 'string',
required: true,
desc: '密码'
},
});
let { username, password } = ctx.request.body;
// 验证该用户是否存在|验证该用户状态是否启用
let manager = await app.model.Manager.findOne({
where: {
username,
}
});
if (!manager) {
ctx.throw(400, '用户不存在或已被禁用');
}
// 验证密码
await this.checkPassword(password, manager.password);
// 记录到session中
ctx.session.auth = manager
return ctx.apiSuccess('ok');
}
// 验证密码
async checkPassword(password, hash_password) {
// 先对需要验证的密码进行加密
const hmac = crypto.createHash("sha256", this.app.config.crypto.secret);
hmac.update(password);
password = hmac.digest("hex");
let res = password === hash_password;
if (!res) {
this.ctx.throw(400, '密码错误');
}
return true;
}
模板:app/view/admin/home/login.html
html
{% extends "admin/layout/main.html" %}
{% block title %} 后台登录 {% endblock %}
{% block body %}
<div class="main-wrapper login-body">
<div class="login-wrapper">
<div class="container">
<div class="loginbox">
<div class="login-left">
<img class="img-fluid" src="/public/assets/img/logo (1).png" alt="Logo">
</div>
<div class="login-right">
<div class="login-right-wrap">
<h1>登 录</h1>
<p class="account-subtitle">Access to our dashboard</p>
<!-- Form -->
<form>
<div class="form-group">
<input class="form-control" type="text" placeholder="输入用户名..." v-model="form.username">
</div>
<div class="form-group">
<input class="form-control" type="text" placeholder="输入密码..." v-model="form.password">
</div>
<div class="form-group">
<button class="btn btn-primary btn-block" type="submit" @click.stop.prevent="submit">登 录</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block js %}
<script>
new Vue({
el: '#vueapp',
data:function(){
return {
form:{
username:"",
password:""
}
}
},
mounted() {
{% if toast %}
this.$refs.toast.show({
msg: "{{toast.msg}}",
type: "{{toast.type}}",
})
{% endif %}
},
methods: {
submit:function(){
var _t = this
$.ajax({
type: "POST",
contentType: "application/json;charset=UTF-8",
url: "/admin/loginevent?_csrf={{ctx.csrf|safe}}",
data: JSON.stringify(this.form),
success: function (result) {
_t.$refs.toast.show({
msg: "登录成功",
type:"success",
success:function(){
window.location.href = "/admin"
},
delay:1000
})
},
error: function (e) {
_t.$refs.toast.show({
msg: e.responseJSON.data
})
}
});
}
},
})
</script>
{% endblock %}
主布局2:app/view/admin/layout/main.html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0">
<title>{% block title %}后台{% endblock %} - 直播后台 </title>
<!-- Favicon -->
<link rel="shortcut icon" type="image/x-icon" href="/public/assets/img/favicon.png">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="http://cdn.bootstrapmb.com/bootstrap/4.3.1/css/bootstrap.min.css">
<!-- Fontawesome CSS -->
<link rel="stylesheet" href="/public/assets/css/font-awesome.min.css">
<!-- Main CSS -->
<link rel="stylesheet" href="/public/assets/css/style.css">
<!--[if lt IE 9]>
<script src="/public/assets/js/html5shiv.min.js"></script>
<script src="/public/assets/js/respond.min.js"></script>
<![endif]-->
{% block css %}{% endblock %}
<!-- jQuery -->
<script src="/public/assets/js/jquery-3.2.1.min.js"></script>
<!-- Bootstrap Core JS -->
<script src="/public/assets/js/popper.min.js"></script>
<script src="http://cdn.bootstrapmb.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<!-- Custom JS -->
<script src="/public/assets/js/script.js"></script>
<script src="/public/assets/js/vue.min.js"></script>
<script src="/public/assets/js/vue.components.js"></script>
</head>
<body>
<div id="vueapp">
{% block body %}{% endblock %}
<confirm ref="confirm"></confirm>
<toast ref="toast"></toast>
</div>
<!-- /Main Wrapper -->
{% block js %}{% endblock %}
</body>
</html>
路由:app/router.js
js
router.get("/admin/login", controller.admin.home.login);
router.post("/admin/loginevent", controller.admin.home.loginevent);