登录功能的实现(包括前后端)

4170 2025-10-31 08:37:02
目录: 🍉🍉🍉UPDATE:✨✨✨前言✨✨✨概述✨✨✨技术栈✨✨✨效果图✨✨✨代码✨✨✨github链接 🍉🍉🍉UPDATE: 突然发现喜提榜一,蟹蟹读者

目录:

🍉🍉🍉UPDATE:✨✨✨前言✨✨✨概述✨✨✨技术栈✨✨✨效果图✨✨✨代码✨✨✨github链接

🍉🍉🍉UPDATE:

突然发现喜提榜一,蟹蟹读者老爷们的支持(づ ̄ 3 ̄)づ

润色了一些格式,加了一些emoji,还配上了一些颜色,希望能在枯燥的技术学习中多一些色彩。

(看了学弟的博客之后发现这样读下去的欲望会大大增加,于是就借鉴了一些hh,在这里强烈推荐一下他的博客:

阳树阳树

是个很厉害,进步超快的博主呢!

✨✨✨前言

登录功能对于前端刚入门不久的我来说较为困难,花了很久查阅了许多资料。代码部分涉及的技术栈和细节也很多。 过了一段时间来看,发现对自己写的代码竟然感觉十分陌生,故想写篇博客,对整个过程进行梳理。方便自己重看代码,同时也希望能帮到在实现这一功能受阻的程序猿

✨✨✨概述

登录功能的实现大致可分成6步:

1.前端验证用户输入是否符合规范,并将账号密码用公钥进行加密

2. 前端调用后端登录接口,向后端发起登录请求

3. 后端收到请求,通过私钥解密后查验数据库中是否有相应账号以及密码是否正确

4.验证通过后,将成功信息连同token一起发送给前端

5.前端将token储存起来,每次用户进入需要登录才能访问的页面时或者每次进入网站时向后端发送token

6. 若过期,则清除用户信息,回到未登录状态

✨✨✨技术栈

前端:JavaScript,Vue

axios (发送请求的第三方库)

element-plus (基于 Vue 3 的组件库,简化UI代码)

后端:Node.js

express (简化请求响应代码)cors (解决跨域问题)bcryptjs(密码加密解密)jsonwebtoken(实现token的生成与验证)

✨✨✨效果图

登陆前

登录界面

登录成功

✨✨✨代码

表单验证及发送请求

axios封装

index.js

import db from "../db/user_db.js"

import bcrypt from "bcryptjs"

import jwt from "jsonwebtoken"

import config from "../config.js"

export async function regUser(req, res) {

try {

// console.log(req.body);

const data = req.body;

// console.log(data.phoneNumber);

const selectSql = "select * from users where phoneNumber=?";

let [result] = await db.query(selectSql, data.phoneNumber)

.catch(err => { console.log(err) });

// console.log(result.length);

//号码已占用

if (result.length > 0) {

throw new Error(res.send({

status: 403,

message: "电话号码已注册过了嗷",

}))

}

//对密码进行加密

// console.log(data.password);

data.password = bcrypt.hashSync(data.password, 10);

console.log(data.password);

const insertSql = "insert into users set ?";

const insertStr = { phoneNumber: data.phoneNumber, password: data.password };

[result] = await db.query(insertSql, insertStr)

.catch(err => { console.log(err) });

// console.log(result.affectedRows);

if (result.affectedRows != 1) {

res.send({

status: 403,

message: "请求失败",

})

}

res.send({

status: 0,

message: "请求成功",

})

} catch (err) {

res.send({

status: 403,

message: "请求失败",

desc: err.message

})

}

}

export async function loginUser(req, res) {

try {

// console.log(req.body);

const data = req.body;

// console.log(data.phoneNumber);

const selectSql = "select * from users where phoneNumber=?";

let [result] = await db.query(selectSql, data.phoneNumber)

.catch(err => { console.log(err) });

// console.log(result);

//无注册账号

if (result.length == 0) {

return res.send({

status: 403,

message: "无注册账号",

})

}

//验证密码

// console.log(result[0].password);

const compareResult = bcrypt.compareSync(data.password, result[0].password);

if (compareResult == 0) {

return res.send({

status: 403,

message: "密码错误",

})

}

const user = { ...result[0], password: '' };

console.log(user);

const tokenStr = jwt.sign(user, config.jwtSecretKey, { expiresIn: "10h" });

return res.send({

status: 0,

message: "登录成功",

token: tokenStr

})

} catch (err) {

return res.send({

status: 403,

message: "请求失败",

desc: err.message

})

}

}

export async function GetInfo(req, res) {

console.log(req.headers.authorization);

const token = req.headers.authorization;

if (!token) {

return res.send({

status: 403,

message: "无token"

})

}

try{

const flag = jwt.verify(token, config.jwtSecretKey);

if (flag) {

return res.send({

status: 0,

message: "验证成功"

})

} else {

return res.send({

status: 403,

message: "token错误"

})

}

}catch(err){

return res.send({

status: 403,

message: "token已过期"

})

}

}

request.js

// http/axios.js

import instance from "./index"

/**

* @param {String} method 请求的方法:get、post、delete、put

* @param {String} url 请求的url:

* @param {Object} data 请求的参数

* @param {Object} config 请求的配置

* @returns {Promise} 返回一个promise对象,其实就相当于axios请求数据的返回值

*/

export const axios = ({

method,

url,

data,

config

}) => {

method = method.toLowerCase();

if (method == 'post') {

return instance.post(url, data, {...config})

} else if (method == 'get') {

return instance.get(url, {

params: data,

...config

})

} else if (method == 'delete') {

return instance.delete(url, {

params: data,

...config

}, )

} else if (method == 'put') {

return instance.put(url, data,{...config})

} else {

console.error('未知的method' + method)

return false

}

}

Login.js

import { axios } from "../utils/request"

export const LoginInPost = (data) => {

return axios({

url: "http://localhost:3007/api/user_login",

method: "post",

data

})

}

export const GetUsersInfo = (data) => {

return axios({

url: "http://localhost:3007/api/get_info",

method: "get",

data

})

}

登录验证

export async function loginUser(req, res) {

try {

// console.log(req.body);

const data = req.body;

// console.log(data.phoneNumber);

const selectSql = "select * from users where phoneNumber=?";

let [result] = await db.query(selectSql, data.phoneNumber)

.catch(err => { console.log(err) });

// console.log(result);

//无注册账号

if (result.length == 0) {

return res.send({

status: 403,

message: "无注册账号",

})

}

//验证密码

// console.log(result[0].password);

const compareResult = bcrypt.compareSync(data.password, result[0].password);

if (compareResult == 0) {

return res.send({

status: 403,

message: "密码错误",

})

}

const user = { ...result[0], password: '' };

console.log(user);

const tokenStr = jwt.sign(user, config.jwtSecretKey, { expiresIn: "10h" });

return res.send({

status: 0,

message: "登录成功",

token: tokenStr

})

} catch (err) {

return res.send({

status: 403,

message: "请求失败",

desc: err.message

})

}

}

✨✨✨github链接

想要看完整版代码以及页面效果,请移步github哦 https://github.com/Ki-Wi-Berry/bilibili-videos

⛄码字不易,如果觉得对您有帮助的话,麻烦点个免费的赞~⛄

新一代AirPods Pro 3上市延後明年!分析師爆料關鍵原因和時程表|AMD APU A6系列