本文字数:约2000字,预计阅读时间10-20分钟。
相信大部分小伙伴在初次接触到Web项目的时候都是从注册登录开始的。
登录注册是互联网项目中非常常见的一个功能,尤其是在网络社交愈发普及的今天,登录注册功能已是必不可少。
登录注册功能的核心功能其实并不复杂,但对于用户账户的安全性要求往往非常高,导致有些尚未工作的大学生甚至工作了几年的程序员对于登录注册的流程不熟悉。
本文以Web网站开发过程中实现的用户登录注册功能为例,探讨一下登录注册功能实现的过程中遇到的问题以及对应的解决方案。
登录注册是互联网应用中非常常见的功能,在讨论为什么之前,我想先说一下它的作用:
最简单的登录注册功能就是:用户输入帐号密码,然后点击登录或者注册,然后处理对应的逻辑,返回给用户成功或者失败。
以下是建表语句示例:
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(255),
password VARCHAR(255)
);
登录界面可以是这样:
小提示:『1』表示为来源于网络,在文末贴有链接。下文同。
处理流程此处忽略......
应该大部分的初学者都是从这一阶段过来的吧...,但是在实际项目当中,仅仅只定义账号密码是肯定不行的。
我们可以想到:使用验证码、对敏感数据如密码等进行加密、添加手机验证或邮箱验证等方法。
这些想法确实不错,我们尝试一下来实现它。
在用户量少的时候,可能把账号密码和用户的基本信息放到同一张表上没什么问题,但如果用户量大了,或者说用户的基本信息字段多了,再放到一张表上,就显得有些臃肿了。
这时候,我们可以利用分库分表的思想,将单一的用户表user
分为用户授权表user_auth
和用户基础信息表user_basic
。
分库分表的基本思想是将数据按照一定的规则分配到不同的数据库中,并且在每个数据库中再按照一定的规则将数据分配到不同的表中。这样,每个数据库和表的数据量都比较小,可以有效地提高数据库的查询速度和存储效率。
在user_auth
表中,我们可以使用identifier
来当做用户登录标识,credential
当做用户秘钥,由于我们考虑到用户可能想通过不止一种方式登录(例如QQ、微信等),所以这里需要identity_type
来当做用户标识类型。
user_basic
表就不必多说了,存放着用户的个人信息,这个可以根据自己的项目来改进。
建表语句举例:
/*
Navicat Premium Data Transfer
Source Server : localhostMySQL8
Source Server Type : MySQL
Source Server Version : 80032
Source Host : localhost:3307
Source Schema : rc
Target Server Type : MySQL
Target Server Version : 80032
File Encoding : 65001
Date: 17/09/2023 17:03:28
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user_auth
-- ----------------------------
DROP TABLE IF EXISTS `user_auth`;
CREATE TABLE `user_auth` (
`id` bigint(0) NOT NULL,
`created_at` datetime(3) NULL DEFAULT NULL,
`updated_at` datetime(3) NULL DEFAULT NULL,
`deleted_at` datetime(3) NULL DEFAULT NULL,
`identity_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户标识类型(邮箱、手机号、token)',
`identifier` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户登录标识',
`credential` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户密钥',
`basic_id` bigint(0) UNSIGNED NULL DEFAULT NULL COMMENT 'basic表的id',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_user_auth_deleted_at`(`deleted_at`) USING BTREE,
INDEX `fk_user_basic_auth_list`(`basic_id`) USING BTREE,
CONSTRAINT `fk_user_basic_auth_list` FOREIGN KEY (`basic_id`) REFERENCES `user_basic` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for user_basic
-- ----------------------------
DROP TABLE IF EXISTS `user_basic`;
CREATE TABLE `user_basic` (
`id` bigint(0) UNSIGNED NOT NULL AUTO_INCREMENT,
`created_at` datetime(3) NULL DEFAULT NULL,
`updated_at` datetime(3) NULL DEFAULT NULL,
`deleted_at` datetime(3) NULL DEFAULT NULL,
`uuid` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户唯一标识',
`nickname` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户昵称',
`avatar` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户头像',
`status` tinyint(1) NULL DEFAULT NULL COMMENT '用户状态',
`phone` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户手机号',
`email` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户邮箱',
`address` varchar(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户地址',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_user_basic_deleted_at`(`deleted_at`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
考虑到SQL语句不直观,下面是我通过Navicat来可视化的表:
页面设计不在此次讨论的范围内,有想要代码的可以在评论区评论。
可以看到,在上图中,我们login接口只传输了一个info
字段,是因为我们将账号和密码进行了加密,我的加密格式是这样的:
例如: identityType|identifier|credential -> 1|123456|mima666
第一步: 先分别AES加密identityType、identifier和credential。
第二步:将三个加密后的字段通过 “|” 分隔符合并成一个字段。
第三步:将合并后的字段进行RSA加密。
这样的话,后端只需要先解密RSA,然后根据|
分割字符串,然后再分别进行AES解密即可拿到原始数据。
由于种种原因,此项目只完成了登录注册功能就被搁浅了,目前正在打算一点一点的完善,此处贴出GitHub地址:https://github.com/rento666/rt-chat
由于时间和篇幅有限,诸如扫码登录、判断IP是否为常住地、MFA校验等更加高级的方式没有探讨,此文章会持续更新,喜欢的可以点个赞、点个收藏。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。