当前位置: 首页 > news >正文

express实现用户登录和注册接口

目录

  • 1 创建数据库
  • 2 连接数据库
  • 3 集成ORM库
  • 4 创建业务逻辑
  • 5 创建路由
  • 7 测试接口
  • 总结

我们在编写后端接口的时候操作数据库是一种常见的功能需求,express本身并不提供直接操作数据库的能力,需要借助第三方库来操作数据库,本篇讲解一下软件开发中像登录和注册如何实现。

1 创建数据库

通常我们编制软件的时候需要选择数据库,我这里选择mysql作为示例,如果你有比较喜欢的数据库也可以按照相同的操作进行。

安装数据库可以参考网上的教程,因为比较普遍这里就不赘述了。数据库安装好之后,用数据库的连接工具来操作数据,我这里用的是navicate,你也可以用别的。

打开我们的navicate,点击连接
在这里插入图片描述
选择mysql
在这里插入图片描述
输入连接名,因为我数据库是在本地,直接输入localhost就行,然后输入数据库的用户名和密码,点击测试连接
在这里插入图片描述
然后点击你的连接名,右键,点击新建数据库
在这里插入图片描述
输入数据库的名称,字符集选择utf8mb4,排序规则选择第一项就可以
在这里插入图片描述
双击数据库名称,选择表,点击新建表
在这里插入图片描述
创建四个字段,分别是username、password、email、id,前三个选择varchar类型就可以,第四个字段需要作为主键,勾选自动增长
在这里插入图片描述
然后点击保存按钮,输入表名即可
在这里插入图片描述
除了可视化的建表外,我们还可以使用sql语句来建表,以下是建表语句

CREATE TABLE users (  id INT AUTO_INCREMENT PRIMARY KEY,  username VARCHAR(50) NOT NULL UNIQUE,  password VARCHAR(255) NOT NULL,  email VARCHAR(100) NOT NULL UNIQUE,  createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,  updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP  
);

还是在navicate里,点击查询、新建查询,输入我们的建表语句
在这里插入图片描述
在这里插入图片描述
点击运行,看到输出的OK就表示表已经创建成功了

2 连接数据库

连接数据库通常需要配置数据库的IP、用户名和密码,我们创建一个环境变量的配置文件来存储这些信息,打开我们的工程,在根目录下创建一个.env的文件
在这里插入图片描述
贴入如下配置

DATABASE_NAME=express  
DATABASE_USER=root  
DATABASE_PASSWORD=111111  
DATABASE_HOST=localhost

具体的配置信息要改成你自己设定的数据库的信息

然后在app.js中读取我们的配置

require('dotenv').config();//加载环境变量

我们使用了dotenv的库,需要先进行安装

npm install dotenv

在这里插入图片描述
完成上述步骤你就可以看到我们的配置信息被正确的读取到了

3 集成ORM库

我们这里使用sequelize来做数据库的操作,orm的好处可以屏蔽具体的数据库语句的细节,在操作数据库的时候可以使用他封装好的API,省了不少事。而且后期如果你想切换数据库,改一下配置文件就可以了。

在项目的根目录创建一个config文件夹,里边创建一个database.js
在这里插入图片描述
贴入如下的配置信息

// 导入 Sequelize 和相应的数据库驱动  
const { Sequelize } = require('sequelize');  
const sequelize = new Sequelize(process.env.DATABASE_NAME, process.env.DATABASE_USER, process.env.DATABASE_PASSWORD, {  host: 'localhost',  dialect: 'mysql', // 根据你的数据库类型选择 'mysql' | 'mariadb' | 'postgres' | 'mssql' | 'sqlite' | 'postgres-native' | 'mariadb-native'  // 其他可能的配置选项  dialectOptions: {  useUTC: true, // 对于不支持 UTC 的数据库,启用这个选项  // 针对特定数据库的额外配置,比如 SSL  },  pool: {  max: 5, // 连接池中的最大连接数  min: 0, // 连接池中的最小连接数  acquire: 30000, // 连接最大等待时间(毫秒)  idle: 10000 // 连接在释放之前可以空闲的最长时间(毫秒)  },  // 其他的 Sequelize 配置项...  logging: console.log, // 启用日志,你可以选择自己的日志函数或者禁用它  
});  // 测试连接  
sequelize  .authenticate()  .then(() => {  console.log('Connection has been established successfully.');  })  .catch(err => {  console.error('Unable to connect to the database:', err);  });  // 导出 Sequelize 实例供其他模块使用  
module.exports = sequelize;

添加配置信息后我们先需要按照库,执行如下命令

npm install sequelize
npm install mysql2

配置创建好之后,需要创建模型层,新建一个model文件夹,里边创建一个User.js
在这里插入图片描述
输入如下配置

// models/User.js  
const { Sequelize, Model } = require('sequelize');  
const sequelize = require('../config/database'); // 假设你有一个数据库配置文件  class User extends Model {}  User.init(  {  email: {  type: Sequelize.STRING,  unique: true,  allowNull: false,  },  password: {  type: Sequelize.STRING,  allowNull: false,  }, username: {type:Sequelize.STRING,allowNull: false, } // 其他字段...  },  {  sequelize,  modelName: 'User',  }  
);  module.exports = User;

如果你的模型和表名不一致,需要指定表名,我这里使用了默认的推断机制,他会转换为小写加一个s的后缀去匹配表,正好是我们的users表

4 创建业务逻辑

我们把业务逻辑封装到service层,这样代码的维护性要好一点,在根目录创建services文件夹,创建一个authService.js

// services/authService.js  
const bcrypt = require('bcrypt');  
const jwt = require('jsonwebtoken');  
const User = require('../models/User');  class AuthService {  async signUp(username, password,email) {  console.log(username,password,email)const salt = await bcrypt.genSalt(10);  const hashedPassword = await bcrypt.hash(password, salt);  const user = await User.create({ username,email, password: hashedPassword });  return user;  }  async signIn(username, password) {  const user = await User.findOne({ where: { username } });  if (!user) throw new Error('User not found');  const isMatch = await bcrypt.compare(password, user.password); console.log("isMatch",isMatch) if (!isMatch) throw new Error('Invalid credentials');  const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET_KEY, { expiresIn: '1h' });  return { user, token };  }  
}  module.exports = AuthService;

这里我们写了两个方法,一个是注册,注册的时候需要给密码加密,登录的时候需要返回给用户一个token,需要安装需要的第三方的库

npm install bcrypt jsonwebtoken

因为我们在创建token时候需要一个密钥,我们也在配置信息里添加,在.env里增加密钥

JWT_SECRET_KEY=d6b522d9a989a9ff8494676b4e1592ea58488b8a4f8126d33d331604e769f4d3

5 创建路由

一切准备就绪之后最后一步就是创建路由了,我们在根目录创建routes,然后创建auth.js
在这里插入图片描述
输入如下代码

// routes/auth.js  
const express = require('express');  
const router = express.Router();  
const AuthService = require('../services/authService');  
const authService = new AuthService();  
// 登录路由  
router.post('/signIn', async (req, res, next) => {  try {  const { username, password } = req.body;  console.log(username,password)console.log(authService)const { user, token } = await authService.signIn(username, password);  res.cookie('token', token, { httpOnly: true, secure: true }); // 假设使用cookie存储token  return res.status(200).json({ code:200,data:{token:token},message:'login success' });  } catch (error) { console.log('error',error.message) if (error.message === 'Invalid credentials'||error.message ==='User not found') {  // 如果是因为无效的凭证,返回401状态码  res.status(401).json({ code:401,message: 'Invalid credentials' });  } else {  // 其他错误,返回500状态码  res.status(500).json({ code:500,message: 'Internal server error' });  // 可能还需要记录错误日志  }  //next(error);  }  
});  // 注册路由  
router.post('/signUp', async (req, res, next) => {  try {  const { username, password ,email} = req.body;  const user = await authService.signUp(username,password,email);  res.status(200).json({code:200,id:user.id});  } catch (error) {  //next(error);res.status(500).json({ code:500,message: 'Internal server error' });   }  
});  module.exports = router;

我们的路由创建好之后要挂载到应用程序里,修改app.js增加路由的挂载代码

const authRouter = require('./routes/auth')//引入权限接口路由
app.use('/api/auth', authRouter);//挂载权限路由

因为接口涉及到参数解析,我们还要启用解析的中间件

// 对于 JSON 请求体  
app.use(express.json());  // 对于 URL 编码的请求体  
app.use(express.urlencoded({ extended: true }));

7 测试接口

接口开发完毕后,就可以进行测试了,这里使用Postman来测试,先测试一下注册接口
在这里插入图片描述
然后再测试一下登录接口
在这里插入图片描述
可以看到两个接口都已经正常返回数据,这样就可以了

总结

本篇我们讲解了一下用户登录和注册接口的开发,涉及到环境变量的初始化,Orm库的搭建以及路由的配置,熟悉了整套流程,后续的功能开发就可以按照自己的需求完成了。

相关文章:

express实现用户登录和注册接口

目录 1 创建数据库2 连接数据库3 集成ORM库4 创建业务逻辑5 创建路由7 测试接口总结 我们在编写后端接口的时候操作数据库是一种常见的功能需求,express本身并不提供直接操作数据库的能力,需要借助第三方库来操作数据库,本篇讲解一下软件开发…...

数字化转型,效率增长才是王道

在当今商业世界,数字化已经成为推动企业增长的强大引擎。然而,值得注意的是,数字化并非只是简单地追求规模扩张,更重要的是实现降本增效。没有效率的增长,就像是在加速自我毁灭。在数字化转型的道路上,企业…...

RHCE-2-chrony服务器

简介 重要性 由于IT系统中,准确的计时非常重要,有很多种原因需要准确计时: 在网络传输中,数据包括和日志需要准确的时间戳 各种应用程序中,如订单信息,交易信息等 都需要准确的时间戳 Linux的两个时钟 硬…...

音频RK809

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、目的二、知识准备2.1Audio框架2.1.1 DAI2.1.2 CODEC2.1.3 machine三、原理图3.1 整体原理图3.2 喇叭部分3.3 麦克风部分四、设备树4.1 sound 部分4.2 codec 部分五、驱动讲...

解决 linux 服务器 java 命令不生效问题

在Linux系统中,当你安装Java并设置了JAVA_HOME环境变量后,你可能需要使用source /etc/profile命令来使Java命令生效。这是因为/etc/profile是一个系统级的配置文件,它包含了系统的全局环境变量设置。 但是需要注意的是,source /e…...

22 多态

目录 多态的概念多态的定义及实现抽象类多态的原理单继承和多继承关系中的虚函数表继承和多态常见的面试问题 前言 需要声明的,下面的代码和解释的哦朴实vs2013x86环境,涉及指针是4bytes,如果要其他平台下,部分代码需要改动。比…...

排序算法超详细代码和知识点整理(java版)

排序 1、冒泡排序 ​ 两层循环,相邻两个进行比较,大的推到后面去,一共比较“数组长度”轮,每一轮都是从第一个元素开始比较,每一轮比较都会将一个元素固定到数组最后的一个位置。【其实就是不停的把元素往后堆&#…...

Java复习第十二天学习笔记(JDBC),附有道云笔记链接

【有道云笔记】十二 3.28 JDBC https://note.youdao.com/s/HsgmqRMw 一、JDBC简介 面向接口编程 在JDBC里面Java这个公司只是提供了一套接口Connection、Statement、ResultSet,每个数据库厂商实现了这套接口,例如MySql公司实现了:MySql驱动…...

Python从零到一构建GPT模型

只用Python和 torch框架,从零到一构建GPT模型,对大语言模型入门,了解GPT的内部网络结构,是一个很好示例。 Build_GPT_from_Scratch.ipynb...

V R虚拟现实元宇宙的前景|虚拟现实体验店加 盟合作|V R设备在线购买

VR(虚拟现实)技术作为一种新兴的技术,正在逐渐改变人们的生活和工作方式。随着技术的不断进步,人们对于元宇宙的概念也越来越感兴趣。元宇宙是一个虚拟世界,通过VR技术可以实现人们在其中进行各种活动和交互。 元宇宙的…...

大话设计模式之策略模式

策略模式是一种行为设计模式,它允许在运行时选择算法的行为。这种模式定义了一族算法,将每个算法都封装起来,并且使它们之间可以互相替换。 在策略模式中,一个类的行为或其算法可以在运行时改变。这种模式包含以下角色&#xff1…...

蓝桥杯23年第十四届省赛真题-三国游戏|贪心,sort函数排序

题目链接: 1.三国游戏 - 蓝桥云课 (lanqiao.cn) 蓝桥杯2023年第十四届省赛真题-三国游戏 - C语言网 (dotcpp.com) 虽然这道题不难,很容易想到,但是这个视频的思路理得很清楚: [蓝桥杯]真题讲解:三国游戏&#xff0…...

P15:PATH环境变量

为什么要配置环境变量 当我们打开DOS窗口,输入:javac,出现下面问题。 原因:windows操作系统在当前目录中无法找到javac命令文件。Windows操作系统是如何搜索硬盘上某一个命令? 首先从当前目录中搜索该命令如果当前目录…...

math模块篇(七)

文章目录 math.dist(p, q)math.hypot(*coordinates)math.sin(x)math.tan(x)math.degrees(x)math.radians(x)math.acosh(x)math.asinh(x)math.atanh(x) math.dist(p, q) 在Python的math模块中,并没有一个名为math.dist(p, q)的函数。可能你是想要计算两点p和q之间的…...

wordpress插件,免费的wordpress插件

WordPress作为世界上最受欢迎的内容管理系统之一,拥有庞大的插件生态系统,为用户提供了丰富的功能扩展。在内容创作和SEO优化方面,有一类特殊的插件是自动生成原创文章并自动发布到WordPress站点的工具。这些插件能够帮助用户节省时间和精力&…...

Remote Desktop Manager for Mac:远程桌面管理软件

Remote Desktop Manager for Mac,是远程桌面管理的理想之选。它集成了多种远程连接技术,无论是SSH、RDP还是VNC,都能轻松应对,让您随时随地安全访问远程服务器和工作站。 软件下载:Remote Desktop Manager for Mac下载…...

如何撰写研究论文

SEVENTYFOUR/SHUTTERSTOCK 即使对于有经验的作家来说,将数月或数年的研究浓缩到几页纸中也是一项艰巨的任务。作者需要在令人信服地解决他们的科学问题和详细地呈现他们的结果之间找到最佳平衡点,以至于丢失了关键信息。他们必须简明扼要地描述他们的方…...

数据结构

一、栈 先进后出 二、队列 先进先出 三、数组 查询快,增加修改慢 四、链表 查询慢,增加修改慢 五、二叉树 节点: 查找二叉树 二叉查找树的特点 二叉查找树,又称二叉排序树或者二叉搜索树 每一个节点上最多有两个子节点 左子树上所…...

动态规划相关题目

文章目录 1.动态规划理论基础2.斐波那契数3.爬楼梯4.使用最小花费爬楼梯5.不同路径6.不同路径 II7. 整数拆分8. 不同的二叉搜索树 1.动态规划理论基础 1.1 什么是动态规划? 动态规划,英文:Dynamic Programming,简称DP,如果某一…...

iOS - Runtime - Class-方法缓存(cache_t)

文章目录 iOS - Runtime - Class-方法缓存(cache_t)1. 散列表的存取值 iOS - Runtime - Class-方法缓存(cache_t) Class内部结构中有个方法缓存(cache_t),用散列表(哈希表)来缓存曾经调用过的方法,可以提高…...

2014年认证杯SPSSPRO杯数学建模B题(第一阶段)位图的处理算法全过程文档及程序

2014年认证杯SPSSPRO杯数学建模 B题 位图的处理算法 原题再现: 图形(或图像)在计算机里主要有两种存储和表示方法。矢量图是使用点、直线或多边形等基于数学方程的几何对象来描述图形,位图则使用像素来描述图像。一般来说&#…...

【物联网项目】基于ESP8266的家庭灯光与火情智能监测系统——文末完整工程资料源码

目录 系统介绍 硬件配置 硬件连接图 系统分析与总体设计 系统硬件设计 ESP8266 WIFI开发板 人体红外传感器模块 光敏电阻传感器模块 火焰传感器模块 可燃气体传感器模块 温湿度传感器模块 OLED显示屏模块 系统软件设计 温湿度检测模块 报警模块 OLED显示模块 …...

Unity中控制帧率的思考

如何控制帧率: 在Unity中,你可以通过设置Application.targetFrameRate来限制帧率。 例如,如果你想将帧率限制为16帧, 你可以在你的代码中添加以下行: Application.targetFrameRate 16; 通常,这行代码会放在…...

阿里云子域名配置,且不带端口访问

进入阿里云控制台,创建一个SSL证书 # 域名名称child.domain.com创建完成后,将返回主机记录以及记录值,保存好,用于下一步使用 创建DNS解析 创建DNS的TXT类型解析 选择记录类型:TXT 填写主机记录:_dnsa…...

C#-ConcurrentDictionary用于多线程并发字典

ConcurrentDictionary 是 .NET Framework 中用于多线程并发操作的一种线程安全的字典集合类。它提供了一种在多个线程同时访问和修改字典时保持数据一致性的机制。 以下是 ConcurrentDictionary 类的一些重要特性和用法: 线程安全性:ConcurrentDictiona…...

深入探讨多线程编程:从0-1为您解释多线程(下)

文章目录 6. 死锁6.1 死锁原因 6.2 避免死锁的方法加锁顺序一致性。超时机制。死锁检测和解除机制。 6. 死锁 6.1 死锁 原因 系统资源的竞争:(产生环路)当系统中供多个进程共享的资源数量不足以满足进程的需要时,会引起进程对2…...

深度学习pytorch——减少过拟合的几种方法(持续更新)

1、增加数据集 2、正则化(Regularization) 正则化:得到一个更加简单的模型的方法。 以一个多项式为例: 随着最高次的增加,会得到一个更加复杂模型,模型越复杂就会更好的拟合输入数据的模型(图-1)&#…...

排序第五篇 归并排序

一 简介 归并排序(Merge Sort) 的基本思想是: 首先将待排序文件看成 n n n 个长度为1的有序子文件, 把这些子文件两两归并, 得到 n 2 \frac{n}{2} 2n​ 个长度为 2 的有序子文件; 然后再把这 n 2 \frac{n}{2} 2n​ 个有序的子…...

【Win】使用PowerShell和Webhooks轻松发送消息至Microsoft Teams

Microsoft Teams是一款由微软开发的团队协作和通讯工具。如果您对这个名字还不太熟悉,那么现在就是一个了解它的好时机。微软将Teams定位为其之前Skype for Business解决方案的继任者,并且它也提供了与其他基于频道的通讯应用程序(例如Slack、…...

ESCTF-OSINT赛题WP

这你做不出来?check ESCTF{湖北大学_嘉会园食堂} 这个识图可以发现是 淡水渔人码头 但是 osint 你要发现所有信息 聊天记录说国外 同时 提示给了美国 你综合搜索 美国 渔人码头 在美国旧金山的渔人码头(英语:Fisherman’s Wharf)是一个著名旅…...

福建住房与城乡建设部网站/seo需要什么技术

Python的特点如下: Python 是一种解释型,交互式,面向对象的高级编程语言。和别的一些使用标点符号的语言不同,Python使用了大量的英语单词作为关键字,因而具有很好的可读性。而且跟其他编程语言相比,它有更…...

wordpress多图片/在线推广企业网站的方法有哪些

在这篇文章里讲述了历史数据的使用。在实际使用时&#xff0c;有时会发现历史数据有个边界问题。下面进行讲解&#xff0c; 一 问题 下面是带历史数据功能的server代码&#xff0c; #include <signal.h> #include <stdlib.h> #include <unistd.h>#include &…...

网站标题优化排名/百度网站官网入口网址

最前面的话&#xff1a;Smobiler是一个在VS环境中使用.Net语言来开发APP的开发平台&#xff0c;也许比Xamarin更方便一、目标样式我们要实现上图中的效果&#xff0c;需要如下的操作&#xff1a;1.从工具栏上的”Smobiler Components”拖动一个一个TableView控件到窗体界面上2.…...

网页设计与制作实用教程(第3版)/网站结构优化的内容和方法

20150803 Created By BaoXinjian 一、摘要 1. JXL 1.1 JXL优点&#xff1a; Jxl对中文支持非常好&#xff0c;操作简单&#xff0c;方法看名知意。 Jxl是纯javaAPI&#xff0c;在跨平台上表现的非常完美&#xff0c;代码可以再windows或者Linux上运行而无需重新编写 支持Excel …...

杀手杰夫链接网站代码/公众号推广引流

众包&#xff08;Crowdsourcing&#xff09;是这样一个过程&#xff1a;征求大批社区中的群众去完成一个任务&#xff0c;传统上这种任务由组织从内部选择一拨人来完成&#xff0c;多数是雇员或合同工。众包测试&#xff08;Crowdsourced testing&#xff09;利用众包的有效性和…...

委托做的网站版权归属/软文代写平台

Windows下vagrant up出现蓝屏的解决办法 版权声明&#xff1a;尊重原创喔&#xff0c;转载请注明 https://blog.csdn.net/lgyaxx/article/details/79333462今天在Windows 10下装了个docker for windows&#xff0c;结果发现问题多多&#xff0c;虽然说container有优势&#xff…...