2024年最新登录功能的实现(包括前后端)_前端登录功能实现,从外包月薪5K到阿里月薪15K

刷面试题

刷题的重要性,不用多说。对于应届生或工作年限不长的人来说,刷面试题一方面能够尽可能地快速自己对某个技术点的理解,另一方面在面试时,有一定几率被问到相同或相似题,另外或多或少也能够为自己面试增加一些自信心,可见适当的刷题是很有必要的。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

  • 前端字节跳动真题解析

  • 【269页】前端大厂面试题宝典

最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。

✨✨✨前言

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

✨✨✨概述

登录功能的实现大致可分成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的生成与验证)

✨✨✨效果图

登陆前
在这里插入图片描述

登录界面
在这里插入图片描述

登录成功

在这里插入图片描述

✨✨✨代码

表单验证及发送请求

<template>
  <el-form
    ref="ruleFormRef"
    :model="ruleForm"
    :rules="rules"
    label-width="35rem"
  >
    <el-form-item prop="phone\_number" class="phone\_number">
      <el-input
        type="text"
        placeholder="你的手机号/邮箱"
        v-model="ruleForm.phone\_number"
      />
    </el-form-item>

    <el-form-item prop="password" class="password">
      <el-input
        type="password"
        placeholder="密码"
        v-model="ruleForm.password"
        autocomplete="off"
      />
    </el-form-item>

    <el-form-item class="login\_in\_button">
      <el-button type="primary" @click="submitForm(ruleFormRef)"
        >登录</el-button
      >
      <el-button>注册</el-button>
    </el-form-item>
  </el-form>
</template>

<script lang="ts" setup>
import { reactive, ref } from "vue";
import type { FormInstance } from "element-plus";
import { ElMessage } from "element-plus";
import { LoginInPost } from "../../api/LoginIn";
import { useRouter } from "vue-router";
import axios from "axios";
import { useStore } from "../../../store.js";
import { storeToRefs } from "pinia";

const router = useRouter();
const store = useStore();
// const { islogin } = storeToRefs(store);

const formSize = ref("default");
const ruleFormRef = ref<FormInstance>();
const ruleForm = reactive({
  phone_number: "",
  password: "",
});

const checkPhonenumber = (rule: any, value: string, callback: any) => {
  if (!value) {
    callback(new Error("请输入注册时用的邮箱或者手机号呀"));
  }
  let re = /^[0-9]\*$/;
  // console.log(value.length);
  // ||value.length != 11
  if (!re.test(value)) {
    // console.log(re.test(value));
    callback(new Error("输入格式有误哟"));
  } else {
    callback();
  }
};

const checkPassword = (rule: any, value: string, callback: any) => {
  if (!value) {
    return callback(new Error("请输入密码呀"));
  }
  let re = /^[0-9a-zA-Z]\*$/;

  if (!re.test(value)) {
    // console.log(re.test(value));
    return callback(new Error("输入格式有误哟"));
  } else {
    return callback();
  }
};

const rules = reactive({
  phone_number: [{ validator: checkPhonenumber, trigger: "blur" }],
  password: [{ validator: checkPassword, trigger: "blur" }],
});

const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  await formEl.validate((valid, fields) => {
    if (valid) {
      let url = "http://localhost:3007/api/user\_register";
      let dataObject = reactive({
        phoneNumber: ruleForm.phone_number,
        password: ruleForm.password,
      });
      try {
        LoginInPost(dataObject).then(function (res) {
          // console.log(res.data.token);
          if (res.data.status == 0) {
            store.loginIn();
            localStorage.setItem("token",res.data.token);
            router.go(-1);
          } else if (res.data.status == 403) {
            ElMessage({ message: res.data.message, offset: 200 });
          }
        });
      } catch (error) {
        console.log(error);
      }
    } else {
      console.log("error submit!", fields);
    }
  });
};
</script>


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;


### 最后

面试一面会问很多基础问题,而这些基础问题基本上在网上搜索,面试题都会很多很多。最好把准备一下常见的面试问题,毕竟面试也相当与一次考试,所以找工作面试的准备千万别偷懒。面试就跟考试一样的,时间长了不复习,现场表现肯定不会太好。表现的不好面试官不可能说,我猜他没发挥好,我录用他吧。

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**

**96道前端面试题:**

- ![](https://img-blog.csdnimg.cn/img_convert/255c6a62691a8c0c44513ce4b200e7c4.webp?x-oss-process=image/format,png)

**常用算法面试题:**

- ![](https://img-blog.csdnimg.cn/img_convert/5977d88812c08dfeb99e63745e7d06f1.webp?x-oss-process=image/format,png)

**前端基础面试题:**
内容主要包括**HTML,CSS,JavaScript,浏览器,性能优化**

- ![](https://img-blog.csdnimg.cn/img_convert/6942bcfcd7fb7a66f544d4974939fae2.webp?x-oss-process=image/format,png)

一样的,时间长了不复习,现场表现肯定不会太好。表现的不好面试官不可能说,我猜他没发挥好,我录用他吧。

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**

**96道前端面试题:**

- [外链图片转存中...(img-gT6GpuNp-1715082382936)]

**常用算法面试题:**

- [外链图片转存中...(img-Q92PADPa-1715082382937)]

**前端基础面试题:**
内容主要包括**HTML,CSS,JavaScript,浏览器,性能优化**

- [外链图片转存中...(img-oB01oBWf-1715082382937)]

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值