【vue3】登录功能怎么实现?

无论是手机端还是pc端,几乎都包含登录注册方面功能,今天总结登录注册功能。

实现功能
注册 密码加密
登录 校验 token处理

1.环境搭建运行(node+express+mongodb)


在目录里安装express和mongoose,并在根目录创建server.js文件和models文件,

在server.js文件中

const express = require('express');
const app = express();

app.listen(3001,() =>{
    console.log('http://localhost:3001')
})


在你models文件中链接MongoDB数据库,express-auth这个就是你数据库的名字,27017是你数据库的端口号,mongodb不需要打开数据库可视化工具,根据名字就自动创建这个数据库名了

const mongoose = require('mongoose')
// 链接数据库
mongoose.connect('mongodb://localhost:27017/express-auth',{
    useCreateIndex:true,
    useNewUrlParser:true
})


在你server.js写一点路由,测试数据库是否链接成功,启动服务的话,你可以全局安装nodemon ,然后通过在命令控制台出入nodemon server.js就可以,会实时更新我们修改的代码,

app.get('/api/test',async(req,res) =>{
    res.send('ok')
})


在这里我们可以在Vcode中安装一个REST Client插件,可以不需要postman就可以调试接口,也是在你的根目录创建一个http结尾的目录。url就是我们的访问域名,定义一个全局的,get就是请求方式,后面test就是请求名。在右边就可以看到我们返回的结果。要在server.js目录引入才能生效。

注册功能

首先建立模型,在models.js建立对应的模型,这里因为是登录和注册,就写两个字段就行,如果需要,可以自行添加对应的字段名,unique表示用户名是唯一的,不让重复添加

userModels.js

const mongoose = require('mongoose');
let userSchema = new mongoose.Schema({
	username: {
		type: String,
		unique:true
	},

	password: {
		type: String,
		set(val) {
			// 通过bcryptjs对密码加密返回值 第一个值返回值, 第二个密码强度
			//需要提前安装(npm install bcryptjs --save)
			return require('bcryptjs').hashSync(val, 10)
		}
	},

});
let userModel = mongoose.model('user', userSchema);

module.exports = userModel

在你user.js文件,先引入这个模型

var express = require('express');
var router = express.Router();
//创建token使用 (安装 npm i jsonwebtoken)
const jwt = require('jsonwebtoken')
const UserModel=require('../models/UserModels.js')

进行登录的验证,登录和注册用的字段一样的。所以不需要建立模型编写,登录时候,第一步肯定先判断用户是不是存在,如果用户不存在,直接返回状态码和错误信息,也不需要执行下一步,第二步用户名过了,接来下就是验证密码是否正确,通过compareSync验证面密码是否正确,如果正确就返回,不正确的话也是返回状态码和错误信息,最后一步就是生成token,返回客户端,客户端可以通过token判断是哪个用户。

//登录账号
router.post('/login',async(req,res) =>{
	//SECRET定义的是一个秘钥,先随便填写,这个秘钥应该不要出现在代码中,
	const SECRET = 'ewgfvwergvwsgw5454gsrgvsvsd'
    const user = await UserModel.findOne({
        username:req.body.username,
    })
	//如果用户名不存在
	if(!user){
		return res.status(422).json({
			        code:'421',
		            message:"用户不存在"
		        })
	}
	//判断密码是否正确
    const isPasswordValid = require('bcryptjs').compareSync(
            req.body.password,
            user.password
        )
		console.log(isPasswordValid);
	if(!isPasswordValid){
		return res.status(422).json({
			  code:'422',
		      message:"密码无效"
		})
	 }
	 //添加token
	  const token = jwt.sign({
	         id:String(user._id)
	     },SECRET)
		 
	 // 生成token
	 res.json({
	 	code: 20000,
	 	msg: '找到了',
	 	data:user,
		token:token
	 })
	
})

token校验

token校验,验证比如获取用户信息,发送什么东西的时候,判断token是否存在,如果存在可以执行,否则不能执行,全局写一个中间件,当每个接口使用的时候,直接调用就可以

const auth = async(req,res) =>{
    const raw = String(req.headers.authorization).split(' ').pop();
    // 验证
    const {id} = jwt.verify(raw,SECRET)
    req.user = await User.findById(id)
}

例如:请求用户列表,需要传token验证是否存在。auth就是验证这个token是否存在。

app.get('/api/profile',auth,async(req,res) =>{
    res.send(req.user)
})

至此后端部分完成,接下来实现前端登录。

2.前端登录(vue3)

2.1 创建utils文件夹

request.ts

import axios from 'axios'

const http= axios.create({
	 baseURL: '/api',// 通用请求地址前缀
	  timeout: 10000,//超时时间
})

// 添加请求拦截器
http.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
http.interceptors.response.use(function (response) {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    return Promise.reject(error);
  });
export default http

2.2 创建api文件夹,存放接口

user.js

import http from '../utils/request'

//登录
export const getLogin= (data) =>{
	//返回一个promise对象
	return http.post('/login',data)
}

2.3 登录页面准备

静态资源页面

<template>
	<div class="login">
		<div class="box">
			<el-form :model="ruleForm" :rules="rules"  ref="ruleData" label-width="100px" class="demo-ruleForm">
				<h3>系统登录</h3>
			  <el-form-item label="账号" prop="username">
			    <el-input placeholder="请输入账号" v-model="ruleForm.username"></el-input>
			  </el-form-item>
			  <el-form-item label="密码" prop="password">
			    <el-input placeholder="请输入密码" type="password" v-model="ruleForm.password"></el-input>
			  </el-form-item>
			  <el-form-item>
			    <el-button type="primary" @click="submitForm(ruleForm)">立即登录</el-button>
			    <el-button @click="resetForm('ruleForm')">重置</el-button>
			  </el-form-item>
			</el-form>
		</div>
	</div>
</template>
<script setup>
	import { ref,reactive } from 'vue';
	import router from '../router';
	
	const ruleForm=reactive({
		username:'',
		password:'',
	})
	
	//定义表单校验规则
	const rules =reactive({
	    username:[
	        {required:true,massage:'请输入用户名',trigger:'blur'},
	        {min:5,max:16,message:'请输入长度5~16非空字符',trigger:'blur'}
	    ],
	    password:[
	        {required:true,massage:'请输入密码',trigger:'blur'},
	        {min:5,max:16,message:'请输入长度5~16非空字符',trigger:'blur'}
	    ],
	})
	
	const ruleData=ref(null)
   
	//重置信息
	const resetForm = () => {
	}
</script>



<style scoped >
	.login{
		display: flex;
		align-items: center;
		background: url(../../src/assets/images/2.jpg) no-repeat;
		background-size: 100%;
		width: 100vw;
		height: 100vh;
		
		
	}
	.box{
		margin: auto;
		padding: 40px;
		width: 500px;
		height: 320px;
		background-color: aliceblue;
		border-radius: 10px;
		box-sizing: border-box;
		
		
	}
	h3{
		color: #222;
		margin: auto;
		margin-bottom: 36px;
		text-align: center;
	}
	.el-button{
		margin-top: 20px;
	}
</style>

2.4 登录功能实现

引入依赖

import Cookies from 'js-cookie'
	import {getUsers,getLogin} from '../api/user.js'
	import { ElMessage } from 'element-plus'

登录功能

const submitForm = (ruleForm) => {
		ruleData.value.validate((valid) => {
			if (valid) {
				getLogin(ruleForm).then(({
					data
				}) => {
					console.log(data);
					if (data.code === 20000) {
						router.push('/article')
						//创建cookies
						Cookies.set('token', data.token)
					} else {
						ElMessage({
							message: '账号密码错误',
							type: 'error',
						})
					}
				})
			}
		})
	}

2.5 在router中添加路由守卫

// 全局守卫:登录拦截 本地没有存token,请重新登录
router.beforeEach((to, from, next) => {
	const token=Cookies.get('token')
	// 判断有没有登录
	if (!token) {
		if (to.name == "login") {
			next();
		} else {
			router.push('login')
		}
	} else {
		next();
	}
});

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值