记录移动开发初探——用uniApp+sqlite仿XyKey实现密码管理记事本

2023-11-18

写在前面

最近刚准备上手移动开发,本着想要多端可用的原则,了解到了uniApp。大致扫完一遍文档,基本可以算是vue+微信小程序原生,对我来说基本0难度可直接进入开发。因此想着索性做一款简单的app来做更加深入的了解。就在这时候,朋友给我推了XyKey这个应用,在使用了一番之后,还是非常有兴趣的,于是打算自己仿XyKey开发一个类似的密码管理记事本。

注:

我自己开发的这个项目灵感来源于:聊一聊我是怎么设计 XyKey,界面UI设计也是仿照XyKey来的。XyKey可在安卓市场免费下载,苹果商店12元可购买,相比较之下我的项目只是仿写,实现了核心功能,但一些优化用户体验的功能我没有做,毕竟我的目的只是研究uniApp。还请大家支持正版。如果本文有涉及任何权益问题请联系我进行删除。

思路

既然是要实现密码管理,那肯定要有数据库存放数据。但对我来说,作为一个后端小白,对于数据库的认知仅仅停留在一些简单的增删改查语句,因此使用mysql,搭建服务器等都是一个难题。而且对于密码管理来说,如果把密码存在服务器的数据库里,也会有被盗取的风险。

这个时候,就要用到sqlite了。

关于sqlite,本文不做过多的介绍了,补一个百科的链接,有需要的小伙伴可以自行百度:百度百科 - sqlite

那么,用到了sqlite之后,我们其实就可以实现纯前端开发一个完整的简单移动应用了。

而在uniApp中要使用sqlite也很简单,只要在manifest.json文件中,在App模块权限配置下勾选sqlite数据库就可以了,非常的方便。

在这里插入图片描述
如果用其他编辑器打开这个文件找不到这个界面的,请使用HbuilderX进行开发。当然在源码里也可以添加代码实现对sqlite的支持,但这个可视化界面更为友好,并且开发完之后也可以直接用Hbuilder打包下载安装。

那么至此,准备工作就做完了,接下来正式进入开发。

最重要考虑的就是安全性方面了。对于普通的应用来说,第一就是用户隔离,也就是你要区分使用者是不同的人,拥有他们自己的数据。这就涉及到了登陆功能,让用户设置一个只有自己知道的登录密码和账号,只有正确之后才可以对自己保存的数据进行操作。但这一点对于sqlite来说没有任何的意义,因为它是嵌入式的,不存在说你的数据库里存着别人的数据。不过,即使这样,我们也不能完全没有限制,像备忘录那样随意使用,这样安全性会很不好。

因此,我一开始的思路就是,还是要建一张user表,只是这里面只有一条数据,就是用户在第一次使用的时候设置的密码。等用户以后使用时,再让用户输入密码,然后和这个设置好的密码进行比对,正确就可以正常使用,不正确就无法使用。

但显而易见的是,这根本就是多此一举。我专门建了一张表,就这么一条数据,然后每次用的时候都要去查一遍,然后比对,正确了才给用,不正确还不给用,非常的不高级,不漂亮。

也是这个时候我才看到本文开篇贴的那个,XyKey设计者谈他的设计思路的那篇文章(其实这时因为我先开发了别的页面和功能,整个项目已经基本开发完,在收尾了。但看到这篇文章之后我受到了很多启发,于是又调整了许多我自己的代码来加入这些思路),于是我就看到了他文章里关于开放式挂载的想法,这让我眼前一亮。

是啊,本身所谓的登录密码,用户体验差不说,在这个情况下也没有任何的意义,干脆去掉算了。可能这时有人就会问了,你刚才不是说,去掉之后,不能保证数据的安全性吗?

其实这里的去掉,并不是完全去掉登录时输入密码这一步,而是不建表去保存,直接把这个作为关键的key。这一点我们可以利用AES的加密解密。关于AES加密,本文也不做过多的展开了,按惯例补一下百科链接:百度百科 - aes

那么,在进行aes加密和解密的时候,是需要一个key作为密码的。如果这个解密时的密码和加密时的密码不一样,解密就会失败。

于是思路就很明显了。用户在刚打开这个应用的时候,还是要输入一个密码。只是这个密码我不会去专门建一张表保存它,而是直接定义一个全局变量存放它。然后,当我需要加密的时候,我就直接使用这个全局变量作为加密时的key,然后存放到数据库里。这个全局变量的值会因为你退出应用而消失。

关键代码:
1.将输入框中的值存入userPwd变量

that.userPwd = e.detail.value;

2.将userPwd存入全局变量

getApp().globalData.userPwd = that.userPwd;

3.加密时,把这个全局变量作为加密的key。注意,这里一开始我直接将密码作为key,但发现解密的时候解不出来,后来我发现这个key一定是要16位的。我本来限制了输入框小于等于16位,所以处理了一下,当用户输入的key不足16位的时候,用a补满,补满之后加密解密正常。

encrypt(word, keyStr) {
	var extraZero = "";
	if (getApp().globalData.userPwd) {
		var num = 16 - getApp().globalData.userPwd.length;
		for (var i = 0; i < num; i++) {
			extraZero += "a";
		}
	}
	var defaultKeyStr = getApp().globalData.userPwd.length != 16 ? getApp().globalData.userPwd + extraZero : getApp().globalData.userPwd;
	keyStr = keyStr ? keyStr : defaultKeyStr;
	var key = CryptoJS.enc.Utf8.parse(keyStr); 
	var srcs = CryptoJS.enc.Utf8.parse(word);
	var encrypted = CryptoJS.AES.encrypt(srcs, key, {
		mode: CryptoJS.mode.ECB,
		padding: CryptoJS.pad.Pkcs7
	});
	return encrypted.toString();
}

这样,用户每次使用这个应用,这个全局变量的值都是全新输入的,而每次需要解密的时候,我都再去读取当前的这个全局变量的值来解密。注意,这个时候,因为用户每一次输入的不一定是上一次加密的时候输入的那个key,所以一旦输入不一致,就无法解出之前保存的密码,实现了登陆功能一样的效果。

关键代码(加密解密其实只是encrypt和decrypt的区别):

decrypt(word, keyStr) {
	...	//这里就不重复写了
	var decrypt = CryptoJS.AES.decrypt(word, key, {
		mode: CryptoJS.mode.ECB,
		padding: CryptoJS.pad.Pkcs7
	});
	return CryptoJS.enc.Utf8.stringify(decrypt).toString();
}

并且,正如XyKey设计者说的那样,这样设计的好处是,用户不管输入什么都可以使用应用了,不会被挡在外面。同时,由于在输入错误的key解不出真正的密码时,他看到的是加密后的数据,也能让他清楚地知道自己的密码数据是被加密了保存的,这让他在使用时更加放心。并且,每个加密的key对应的数据都是独立的,用户可以自由的决定哪个key可以看到哪些密码,极大地提高了可扩展性。

页面预览:

我自己开发的项目中,我也对分类做了一些自己的处理。XyKey是没法增加或者删除分类的,只能修改已有分类。我认为这里可扩展性不够,因此我开发时,规定分类至少要有一个,并且只有在此分类下没有保存的密码数据时,我才允许删除这个分类。我允许用户新建分类,也会在一开始给一个叫默认的分类,当然这个默认的分类也是可以被修改名字和被删除的。

页面预览:

关于建表的话,我是建了一张account表存放密码数据,一张type表存放分类数据。本来还建了一张extra表用于存放新增密码数据时的自定义新内容(也就是在新建密码数据时,除了我写好的一些必填的内容,用户也可以按自己想要的去新增一项然后填写自己想记录的内容,这个无论是数量还是具体内容都是很自由的,所以单独建一张表存放,然后用id绑到对应数据上),但因为这里不作深入展开了,所以暂时搁置,等真正要完善这个项目的用户体验时再完成。

至此,核心功能的思路就差不多讲完了。

补一下uniApp执行SQL语句的代码:

executeSQL(sql, successCallback, failCallBack) {
	var that = this;
	plus.sqlite.executeSql({
		name: 'chrisPWNoteDB',
		sql: sql,
		success: function(data) {
			console.log('executeSql success!' + JSON.stringify(data));
			if (successCallback) {
				successCallback(data);
			}
		},
		fail: function(e) {
			console.log('executeSql failed: ' + JSON.stringify(e));
			if (failCallBack) {
				failCallBack(e);
			}
		}
	});
}

和点击复制文字内容的方法:

copyText() {
	var that = this;
	if(that.clipBordText){
		uni.setClipboardData({
			data: that.clipBordText
		});
	}
}

其他看了看也没什么特别要交代的了,都是uniApp开发文档里现成的内容,就不搬来搬去了。源码本来是放在github上的,但考虑到因为是仿写别人的项目,就暂时没有公开。有想要研究的可以问我要。我也可以直接打个安卓包给你(苹果暂时不行),然后你自己去下载Xykey比较一下使用体验。

后话

uniApp是可以直接使用scss的哦,不需要额外安装插件!当然这里对于scss也不展开讲了,但它提供的变量、嵌套、混合、继承等特性,懂的都懂!(我快写完了才发现的,改了一小部分,懒得再改了,说多了都是泪)

补一下

有小伙伴私信我说,你这个虽然用的是uniApp,但你用sqlite的话,也就只能用在安卓端和ios端,各平台小程序和h5都不支持。

对于这个问题,我想说这位小伙伴说的没错,但我是这样想的,首先对于这个项目而言,他的功能决定了它比较适合成为一个本地应用,而不是像小程序或h5那样在浏览器上,去联网(联网就有被窃取数据的风险)。

其次就是,这也是我刚刚接触移动开发,其实本身就比较偏向用uniApp去代替安卓原生和ios原生来开发移动APP,只要安卓和ios能通用就算完成目标,毕竟我本身对原生小程序开发还是比较熟悉的,小程序端的项目不太需要用uniApp来完成(我也会用mpvue,但这个吧我个人不太爱)。

当然后面有时间了也会专门用uniApp去开发一个多平台通用的小程序,那就是后话了。

感谢小伙伴给我的反馈,后面我也会尽量讲清楚的~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

记录移动开发初探——用uniApp+sqlite仿XyKey实现密码管理记事本 的相关文章

  • AutoCompleteTextView sqlite填充异常

    我的第一篇文章只有不到一半的文字 因此是第二篇 完整的 文章 我正在开发一个测试应用程序 使用 sqlite 填充两个 AutoCompleteTextView 我正在使用汽车制造商和模型进行测试 自动完成的 使自动完成 模型自动完成 ma
  • 从什么时候起sqlite的持久日志模式成为Android中的默认日志模式?

    从什么时候起sqlite的持久日志模式成为Android中的默认日志模式 我知道Android版本4 1 1 API 16 中的日志模式已经改变 但这并不准确 因为发行说明中不包含此信息 我不知道是否可以在发行说明中找到 如果您认识的人确切
  • 如何将子集合添加到 Firestore 中的文档? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 没有关于如何在Firestore中的文档中添加子集合的文档 那么如何使用Web应用程序添加子集合 我尝试了这个但没有成功 如何使用代码
  • 仅当 id 不存在时插入

    好的 我们有一个 Phonegap 应用程序 其表格设置如下 tblTest actualid INTEGER PRIMARY KEY id INTEGER name TEXT 实际 ID 是设备的唯一 ID 该 ID 维护在服务器端数据库
  • 关于android Sqlite在多进程情况下的安全性

    在我的应用程序中 存在多个进程 并且在每个进程中 我需要访问同一个SQLite数据库 当然 这意味着超过2个线程 所以我不仅担心SQLite的线程安全性 还担心SQLite的线程安全性 还有过程安全 这种情况的一种解决方案是使用内容提供者
  • PHP - SQLite 与 SQLite3

    我已经使用 SQLite 2 8 17 制作了一个 Web 应用程序 我现在才发现有一个 SQLite3 在制作 Web 应用程序时 它以某种方式逃避了我的注意 可能是由于缺少 php 函数的文档 我想知道 使用 SQLite3 比 SQL
  • 不使用窗口函数实现 SQL 查询

    我读过 可以通过创造性地使用连接等来实现在 SQL 窗口函数中可以执行的任何操作 但我不知道如何实现 我在这个项目中使用 SQLite 它目前没有窗口函数 我有一个有四列的表 CREATE TABLE foo id INTEGER PRIM
  • 当添加列较少时追加到现有 SQLite 表,而不将数据库读入 R

    是否有一些简单的方法 无论是在 SQL 端还是在 R 端 将 data frame 附加到具有更多列的现有表 缺失的列应该用 NA 填充 如果它能够优雅地处理比表 1 列数更多的表 2 那么会加分吗 library RSQLite Crea
  • Vuejs 在模板中添加多行?

    我想知道在构建 Vuejs 模板时如何最好地安排新行 我的代码不起作用 因为它破坏了 JavaScript 容器 Vue js 希望我将整个 html 放在一行中 当我计划添加页脚内容时 这有点不切实际 Vue component foot
  • 如何从 Laravel 将路由参数传递到 Vue.js

    我有这样的路线来获取带有相关评论的帖子 Route get api topics category id title function category id title return App Topic with comments gt
  • Vue 3 - 如何使用反应式引用并在没有 .value 的情况下进行计算?

    当我们使用选项 API https v3 vuejs org api options api html 我们可以在中定义一些属性computed部分和一些属性data部分 所有这些都可以通过实例从实例访问this引用 即在同一个对象中 非常
  • 使用 SQLite 和 Python 从数据库读取:提供的绑定数量不正确

    我使用以下 python 脚本读取数据库 cur execute SELECT FROM pending where user ID 其中 ID 是某人的名字 在本例中为 Jonathan 但是 当我尝试运行此脚本时 我收到错误消息 Tra
  • 错误:找不到模块 \node_modules\sqlite3\lib\binding\electron-v8.0-win32-x64\node_sqlite3.node'

    我在 Electron 8 1 中安装 sqlite3 时遇到问题 我收到以下错误 Error Cannot find module D TASK 2020 1 1 AMS node modules sqlite3 lib binding
  • 如何更改Python使用的SQLite版本?

    我在 Debian 9 12 上安装了 Python 3 8 和 SQLite 3 16 2 并且需要升级到较新版本的 SQLite 我已经下载并编译了 SQLite 网站上提供的合并 并将其放入 usr bin 所以当我这样做时 sqli
  • 可以使用两个独立的 SQLite 数据库吗?

    我有一个 sqlite 数据库 其中存储用户定义的信息和用户只读的信息 我觉得将来可能需要修改只读信息 并且我不想进行整个数据迁移 有没有一种方法可以使用单独的 sqlite 数据库来存储只读信息 该数据库可以轻松替换 如果是这样 您能否就
  • 如何在SQLite中的两个表之间复制数据?

    我有两个具有不同列的表 如下所示 table1 id title name number address table2 id phone name address 如何将数据 名称 地址 从表 1 复制到表 2 我的问题有两种情况 第一 t
  • 如何将函数导入到Vue组件中?

    我正在尝试将单个函数导入到我的 Vue 组件中 我为我的函数创建了一个单独的 js 文件 randomId js exports randomId gt My function 在我的 Vue 组件中 我导入了 Random js let
  • Android 错误 - close() 从未在数据库上显式调用

    我应该在代码的哪里调用 close LogCat 返回此错误 close 从未在数据库上显式调用 android database sqlite DatabaseObjectNotClosedException 应用程序未关闭此处打开的游标
  • 从SQLite列中获取所有数字字符串并进行总和计算

    我是 Android 和 SQLite 的新手 我在 SQLite 中有一个只有数字的 AMOUNT 列 我可以在 ListView 中显示它 但我无法找到任何我理解的方法来将它们全部添加并显示在 TextView 中 这是数据库助手 im
  • Heroku 上重启后 Better-SQLite3 数据库重置

    我有一个 Discord 机器人better sqlite3 https github com JoshuaWise better sqlite3硬币和 XP 数据库 直到两周前它一直工作得很好 现在 每次重新启动后 它只会恢复 XP 和硬

随机推荐

  • 算法训练营第十一天(7.22)

    目录 LeeCode20 Valid Parentheses LeeCode1047 Remove All Adjacent Duplicates In String LeeCode150 Evaluate Reverse Polish N
  • 第三章 3.1节练习 & 3.2.2节练习

    练习3 1 使用恰当的using声明重做1 4 1节 11页 和2 6 2节 67页 的练习 解答 这里就不写代码了 因为可以using命名空间或者空间中的对应函数 可以出现很多种组合 可以按照自己喜欢或熟悉的方式来写 练习3 2 编写一段
  • python 面向对象 超级详细全面讲解

    如有错误 欢迎留言指出讨论 1 面向对象和面向过程 1 1 面向过程注重的是结果 从结果出发去考虑问题的实现步骤 1 2 面向对象注重的是设计 从现实生活的角度 从设计的角度去考虑问题的实现步骤 1 3 虽然2种思想的目的都是为了做出一个程
  • 00后视频审核员,3个月顺利转行车载测试,他说你也能行!

    21年夏天毕业后 自觉比较社恐的我去找了一份看似清闲又不用和逼人打交道太多的工作 原本以为这份工作会成为我的庇佑所 没想到也是一地鸡毛 是的 我是一个视频审核 顾名思义 作为一个视频审核员 毫无疑问我的工作就是看视频 也许有人会说 就看看视
  • numpy中np.array()功能

    功能 将数据转化为矩阵 a 1 2 3 4 5 6 7 8 9 b np array a c np asarray a a 2 1 print a print b print c 从中我们可以看出np array与np asarray功能是
  • JAVA并发队列

    Java并发队列 在并发队列上JDK提供了两套实现 一个是以ConcurrentLinkedQueue为代表的高性能队列 一个是以BlockingQueue接口为代表的阻塞队列 无论哪种都继承自Queue 一 ConcurrentLinke
  • 【Hbase 05】Hbase表的设计原则与优化方案

    这里说一下Hbase在使用过程中的表设计原则与优化方案 如果你是运维或者开发兼顾环境的工作 也许比较受用 话不多说 我们直接开始说优化的内容 一 表设计原则 1 行键设计 行键在设计的时候要尽量的散列 例如可以考虑使用哈希 加密算法等使结果
  • 在Webpack 5 中如何进行 CSS 常用配置?

    本文摘要 主要通过实操讲解运用Webpack 5 CSS常用配置的方法步骤 前文已谈到可以通过配置 css loader 和 style loader 使 webpack5 具有处理 CSS 资源的能力 css loader 首先会分析出各
  • 【线性代数】向量组的线性相关性

    文章目录 向量组及其线性组合 一 向量 二 线性表示 1 线性组合的定义 2 线性表示的定义 3 线性表示的充要条件 三 向量组等价 1 向量组等价定义 2 向量组线性表示的充要条件 3 向量组等价的充要条件 4 向量组线性表示的必要条件
  • 如何设计企业节点的『工业互联网标识解析系统』

    一 星火 链网 体系架构 星火 链网 以节点形式进行组织互联互通 其中包括三类节点 超级节点 骨干节点 业务节点 其底层采用 1 N 主从链群架构 支持同构和异构区块链接入主链 在全国重点区域部署 星火 链网 超级节点 作为国家链网顶层 提
  • Waffle使用初体验

    一 什么是Waffle Waffle是什么呢 我们直接看其文档上的介绍 Waffle is a library for writing and testing smart contracts Sweeter simpler and fast
  • 主要进行OGRE引擎和shader

    今天 老大告诉我 只要把GLSL进行就行了 其余不用管 那就与OGRE相结合 轮流进行即可 看看引擎架构 搞搞shader
  • HDC即将开始,有哪些亮点值得期待?

    鸿蒙新版本即将发布 开发者该如何紧跟生态热点 最重磅的当然是HarmonyOS 3 1beta版本将于11月4日在华为开发者大会2022 HDC 现场宣布发布 代表着鸿蒙生态新的征程 除正式发布外 最近华为开发者学堂已经上线的一些鸿蒙生态相
  • 北大硕士7年嵌入式学习经验分享

    01 前言 大家现在状态是怎么样的 这几年技术进步怎么样 职场晋升 管理水平有没有提升 欢迎留言 本文内容来自于知乎 觉得内容很不错 分享给大家 下文的我代表的是原作者 作者 梦人亦冷 链接 https www zhihu com ques
  • 数据库查询语句

    数据库查询语句无疑是所有语句中 最重要的语句 经常配合where一起使用 1 最基本的查询 公式1 select from 表名 查看aaa表中的所有数据 SELECT FROM aaa 你说 我不想查看表中所有的数据 我就想查看表中id字
  • Python进行大数据挖掘和分析

    大数据无处不在 在时下这个年代 不管你喜欢与否 在运营一个成功的商业的过程中都有可能会遇到它 什么是大数据 大数据就像它看起来那样 有大量的数据 单独而言 你能从单一的数据获取的洞见穷其有限 但是结合复杂数学模型以及强大计算能力的TB级数据
  • 中国大陆网站TOP100

    1 新浪新闻中心 包括即日的国内外不同类型的新闻与评论 人物专题 图库 BR www sina com cn 2 Baidu com 全球最大中文搜索引擎 向人们提供简单 可依赖的信息获取方式 BR www baidu com 3 搜狐 资
  • VMware Vsphere-下

    18 创建资源池和vAPPs 主机右击可以看到 新建资源池 资源池里可以指定资源池所消耗的物理的cpu和内存 份额 预留 限制 资源池里面可以放虚拟机 资源池的作用 可以将几台虚拟机放进一个池 限制资源 这样就不会出现一个虚拟机抢占过多资源
  • vue3知识点:Suspense组件

    文章目录 五 新的组件 3 Suspense 案例 完整代码 本人其他相关文章链接 五 新的组件 3 Suspense 等待异步组件时渲染一些额外内容 让应用有更好的用户体验 使用步骤 第1步 异步引入组件 import defineAsy
  • 记录移动开发初探——用uniApp+sqlite仿XyKey实现密码管理记事本

    写在前面 最近刚准备上手移动开发 本着想要多端可用的原则 了解到了uniApp 大致扫完一遍文档 基本可以算是vue 微信小程序原生 对我来说基本0难度可直接进入开发 因此想着索性做一款简单的app来做更加深入的了解 就在这时候 朋友给我推