技能学习:学习使用Node.js + Vue.js,开发前端全栈网站-12-1.管理员模块

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 网站的必备功能:用户登录。用户登录功能是网站安全的一大重点,网站做的再好看,再完善,如果没有一个安全的管理员通道,都算不上一个成功的网站。今天起的几篇文章对用户登录进行专门学习。本篇文章我们将管理员模块实现。

网站的必备功能:用户登录。
用户登录功能是网站安全的一大重点,网站做的再好看,再完善,如果没有一个安全的管理员通道,都算不上一个成功的网站。今天起的几篇文章对用户登录进行专门学习。
本篇文章我们将管理员模块实现。

1.管理员模块的实现

我们使用了CRUD通用接口,我们不需要对常用接口进行编辑,所以每个数据表的模型是我们开发一个模块时的第一步。模型Admin.js,只包括用户名密码即可:
在这里插入图片描述
主页面Main.vue添加导航:
在这里插入图片描述
AdminSet.vue:

<template>
    <div>
        <h1>{{id ? '编辑' : '创建'}}管理员</h1>
        <el-form label-width="80px" style="margin-top:20px;" @submit.native.prevent="save">
            <el-form-item label="用户名">
                <el-input v-model="model.username"></el-input>
            </el-form-item>
            <el-form-item label="密码">
                <el-input type="password" v-model="model.password"></el-input>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" native-type="submit">保存</el-button>
            </el-form-item>
        </el-form>
    </div>
</template>
<script>
export default {
    props: {
        id: {}
    },
    data(){
        return {
            model: {},
            parentOptions: [],
        }
    },
    methods: {
        async save(){
            let res
            if(this.id){
                res = await this.$http.put('rest/admins/' + this.id, this.model)
            }else{
                res = await this.$http.post('rest/admins', this.model)
            }
            console.log("en?",res)
            this.$router.push('/admins/list')
            this.$message({
                type: 'success',
                message: '保存成功'
            })
        },
        async fetch(){
            const res = await this.$http.get('rest/admins/' + this.id)
            this.model = res.data
        },
    },
    created(){
        this.id && this.fetch()
    }
}
</script>

AdminList.vue:

<template>
    <div>
        <h1>分类列表</h1>
        <el-table :data="items">
            <el-table-column prop="_id" label="ID" width="220">
            </el-table-column>
            <el-table-column prop="username" label="用户名">
            </el-table-column>
            <!-- 列表页没必要将用户密码显示 -->
            <!-- <el-table-column prop="password" label="密码">
            </el-table-column> -->
            <el-table-column
            fixed="right"
            label="操作"
            width="100">
                <template slot-scope="scope">
                    <el-button type="text" size="small" @click="$router.push('/admins/edit/' + scope.row._id)">编辑</el-button>
                    <el-button @click="remove(scope.row)" type="text" size="small">删除</el-button>
                </template>
            </el-table-column>
        </el-table>
    </div>
</template>
<script>
export default {
    data() {
        return {
            items: []
        }
    },
    methods: {
        async fetch(){
            const res = await this.$http.get('rest/admins')
            this.items = res.data
        },
        remove(row){
            this.$confirm('是否确定要删除"' + row.name + '"的账号?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(async () => {
                // 要想使用await,函数必须使用async
                // await异步执行,待调用接口获取数据完成后再将值传给res,进行下一步操作
                const res = await this.$http.delete('rest/admins/' + row._id)
                this.$message({
                    type: 'success',
                    message: '删除成功!'
                });
                if(res.status == 200){
                    // 接口调用成功后,刷新页面
                    this.fetch()
                }
            }).catch(() => {
                this.$message({
                    type: 'info',
                    message: '已取消删除'
                });          
            });
        }
    },
    created() {
        this.fetch()
    }
}
</script>

为组件添加路由:
在这里插入图片描述
测试一下,
在这里插入图片描述
没问题。

2.用户的密码安全

虽然我们的密码输入框使用了password加密,将密码转化为*号,但是想要查看用户密码还是很简单的。
在这里插入图片描述
在任何登录功能中,密码不仅关系到用户的信息安全,还涉及到了用户的隐私。部分用户为了配合现阶段的密码强度(字母、数字、符号组合等),都有各自固定的密码格式,也就是说为了方便记忆,一个用户在各个平台使用的大多数账号都是相同的密码。所以本着程序工作者的职业操守,我们有义务为使用我们产品的用户进行密码转码操作,从而保护用户的隐私。
(1)修改管理员数据模型
在这里插入图片描述
加密过程不在前端,而是将密码传输到服务端,在服务端对密码进行重新散列编码,保存到数据库的就是重新编码后的密码。
(2)使用bcryptjs加密包

cd server
npm i bcryptjs

在这里插入图片描述
安装成功,引入bcryptjs:

const mongoose = require('mongoose')

const schema = new mongoose.Schema({
    username: { type: String },
    // 默认是将接收到的password直接保存到数据库
    // 我们现在要使用函数对接收到的值进行加密操作,然后return出去到数据库
    password: { 
        type: String, 
        set(val){
            // 引入bcryptjs,hashsync同步方法传入val值,10是散列值(值越大转码强度越大但转化时间越长,一般在10-12)
            return require('bcryptjs').hashSync(val, 10)
        } 
    },
})

module.exports = mongoose.model('Admin', schema)

保存密码测试,再打开:
在这里插入图片描述
已经是加密格式,且不可逆。
(3)bcryptjs加密的优势
我们熟知的md5加密只是将密码按规律转码成另一种密码形式,是可以进行逆向破解的。
但是bcryptjs的加密方式每次生成的编码是不同的,所以就算我们看到了编码,也不可能按照编码的规律反向推断出用户密码,所以说是绝对加密的。
在这里插入图片描述
可以看到现在输入123456保存后显示的编码是IY3W结尾,我们再次填写123456保存测试:
在这里插入图片描述
形成的编码是UraO结尾,可见同样的密码,加密后的编码也不一样,我们不管怎样都是无法查询到用户密码的。
(4)隐藏密码数据
既然我们对密码进行了加密,密码的显示对我们就没什么用处了。但是我们仍然要保留修改密码的方法。此时我们将密码数据隐藏。
在这里插入图片描述
刷新之后密码就不会被查询出来了。
在这里插入图片描述

下篇文章我们编写登陆页面和登录接口,学习编码后的密码如何校验并登录。

相关文章
|
2月前
|
前端开发 机器人 API
前端大模型入门(一):用 js+langchain 构建基于 LLM 的应用
本文介绍了大语言模型(LLM)的HTTP API流式调用机制及其在前端的实现方法。通过流式调用,服务器可以逐步发送生成的文本内容,前端则实时处理并展示这些数据块,从而提升用户体验和实时性。文章详细讲解了如何使用`fetch`发起流式请求、处理响应流数据、逐步更新界面、处理中断和错误,以及优化用户交互。流式调用特别适用于聊天机器人、搜索建议等应用场景,能够显著减少用户的等待时间,增强交互性。
611 2
|
1月前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
2月前
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
55 0
|
1月前
|
JavaScript 前端开发 Java
springboot解决js前端跨域问题,javascript跨域问题解决
本文介绍了如何在Spring Boot项目中编写Filter过滤器以处理跨域问题,并通过一个示例展示了使用JavaScript进行跨域请求的方法。首先,在Spring Boot应用中添加一个实现了`Filter`接口的类,设置响应头允许所有来源的跨域请求。接着,通过一个简单的HTML页面和jQuery发送AJAX请求到指定URL,验证跨域请求是否成功。文中还提供了请求成功的响应数据样例及请求效果截图。
springboot解决js前端跨域问题,javascript跨域问题解决
|
1月前
|
JSON 前端开发 JavaScript
聊聊 Go 语言中的 JSON 序列化与 js 前端交互类型失真问题
在Web开发中,后端与前端的数据交换常使用JSON格式,但JavaScript的数字类型仅能安全处理-2^53到2^53间的整数,超出此范围会导致精度丢失。本文通过Go语言的`encoding/json`包,介绍如何通过将大整数以字符串形式序列化和反序列化,有效解决这一问题,确保前后端数据交换的准确性。
40 4
|
1月前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
129 1
|
1月前
|
移动开发 前端开发 JavaScript
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
于辰在大学期间带领团队参考网易游戏官网的部分游戏页面,开发了一系列前端实训作品。项目包括首页、2021校园招聘页面和明日之后游戏页面,涉及多种特效实现,如动态图片切换和人物聚合效果。作品源码已上传至CSDN,视频效果可在CSDN预览。
45 0
|
1月前
|
JavaScript 前端开发 开发者
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第27天】在前端开发领域,Vue.js和Angular是两个备受瞩目的框架。本文对比了两者的优劣,Vue.js以轻量级和易上手著称,适合快速开发小型到中型项目;Angular则由Google支持,功能全面,适合大型企业级应用。选择时需考虑项目需求、团队熟悉度和长期维护等因素。
52 1
|
1月前
|
JavaScript 前端开发 API
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第26天】前端技术的飞速发展让开发者在构建用户界面时有了更多选择。本文对比了Vue.js和Angular两大框架,介绍了它们的特点和优劣,并给出了在实际项目中如何选择的建议。Vue.js轻量级、易上手,适合小型项目;Angular结构化、功能强大,适合大型项目。
42 1
|
1月前
|
前端开发 JavaScript UED
"前端小技巧大揭秘:JS如何将后台时间戳秒变亲切小时前、分钟前,让用户秒懂,提升互动体验!"
【10月更文挑战第23天】在Web开发中,将后台返回的时间戳转换为“小时前”、“分钟前”、“刚刚”等友好的时间描述是常见需求。本文介绍如何用JavaScript实现这一功能,通过计算当前时间和时间戳的差值,返回相应的描述,提升用户体验。
43 1