登录注册完整流程
开发场景描述:当准备从零开始做一个项目时,此时前后台同时开发,由于后台可能会由于时间问题不能提供数据,此时就需要前端人员模拟数据,例如Mock。在外面的Vue中,同样可以实现mock的操作模拟数据。需要对 JWT (Json Web Token) 和 token 有一定认知。实现登录部分第一步 :搭建vue基本项目框架,前端安装 npm i --save axios ,创建一个登录页面 Login
·
开发场景描述:
当准备从零开始做一个项目时,此时前后台同时开发,由于后台可能会由于时间问题不能提供数据,此时就需要前端人员模拟数据,例如Mock。在外面的Vue中,同样可以实现mock的操作模拟数据。
需要对 JWT (Json Web Token) 和 token 有一定认知。
· 首先打开Apache 和 MySQL
实现登录部分
- 第一步 :搭建vue基本项目框架,前端安装 npm i --save axios ,创建一个登录页面 Login
<template>
<div>
账号:<input type="text" placeholder="账号" v-model="username">
密码:<input type="text" placeholder="密码" v-model="password">
<button @click="myLogin">登录</button>
</div>
</template>
<script>
export default {
data(){
return{
username:"",
password:""
}
},
methods:{
myLogin(){
//登录流程
}
}
}
</script>
- 第二步 :将Login引入路由并配置
- 第三步:用 mock 模拟后台数据,在项目根目录下创建一个 mock 文件夹,打开终端安装 npm i --save express axios ,mock下分别创建两个文件index.js 和 router.js
index.js文件
const express = require("express");
const app = express();
const router = require("./router")
const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({
extended:true
}))
app.use("/api",router)
app.listen(3000,() =>{
console.log("服务器运行在3000端口上");
})
router.js文件
const express = require("express");
const router = express.Router();
router.post('/login',(req,res)=>{
const username = req.body.username;
const password = req.body.password;
if(username && password){
res.send({
msg:"登录成功",
code:200
})
}else{
res.send({
msg:"登录失败",
code:400
})
}
})
module.exports = router;
- 先用 postman 测试,这样容易分别是前端出错还是后台出错,如果可以获取成功后执行下一步
- 回到前台,创建 utils 文件夹,里边创建 request.js 并配置
//封装网络请求:Axios
import axios from "axios"
import qs from "query-string"
// 错误信息的响应方法
const errorHandle = (status,other) => {
switch(status){
case 400:
// 请求头和服务器的限制
console.log(" 服务器不理解请求的语法");
break;
case 401:
// token验证失败,用户身份验证失败
console.log("(未授权) 请求要求身份验证");
break;
case 403:
// 用户身份过期了,服务器请求限制
console.log("(禁止) 服务器拒绝请求");
break;
case 404:
// 网络请求地址错误
console.log("(未找到) 服务器找不到请求的网页。");
break;
default:
console.log(other);
break;
}
}
// 创建axios对象
const instance = axios.create({
timeout:5000 // 请求超时
})
// 全局配置
instance.defaults.baseUrl = "http://iwenwiki.com";
// instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;
instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
// 创建请求拦截和响应拦截操作
instance.interceptors.request.use(config =>{
// 配置
if(config.method === 'post'){
config.data = qs.stringify(config.data);
}
return config;
},
error => Promise.reject(error)
)
instance.interceptors.response.use(
// 成功
/**
* 成功和失败的判断:
* 1.请求成功和请求失败
* 2.请求成功:结果的成功和结果的失败
*
* 真正好的代码:
* 1.可读性高
* 2.可维护性强
* 不是流水账的代码!!!
* 面向对象的思维方式:OOP
*/
response => response.status === 200 ? Promise.resolve(response) : Promise.reject(response),
// 我们自己封装的,所以为了代码的清晰可读性,我们需要增Promise
// response => response,
error => {
const { response } = error; // ES6的解构赋值
/**
* response包含的信息:
* status
* data
*/
if(response){
// 给出开发者具体的错误信息
errorHandle(response.status,response.data);
return Promise.reject(response);
}else{
console.log("请求中断或者断网了");
}
}
)
export default instance;
再创建一个 api 文件夹,里边分别创建 base.js 用来存储路径;index.js 来存储封装的网络请求
//base.js文件
const base = {
baseUrl:'/api',
login:'/api/login'
}
export default base;
//index.js文件
import base from './base'
import axios from '../utils/request'
const api = {
// 登录接口
getLogin(params){
return axios.post(base.baseUrl + base.login,params)
}
}
export default api;
- 解决跨域问题:在项目根目录下创建一个vue.config.js配置文件并设置配置项:
//vue.config.js文件
module.exports = {
devServer:{
proxy:{
"/api":{
target:"http://localhost:3000/",
pathRewrite:{ //重写路径
"^/api":""
},
changeOrigin:true //允许跨域
}
}
}
}
- 在Login组件中获取数据
methods:{
myLogin(){
this.$api.getLogin({
username:this.username,
password:this.password
}).then(res=>{
console.log(res);
})
}
}
实现登录验证部分
场景:点击进入 about 页面验证用户是否登录,如果登录成功则可以进入 about 页面,如果用户未登录或者登录不成功则自动跳转到 Login 登录页面。这里有两个知识点 token 和 jwt(json web token)
- 第一步:给 about组件设置路由元信息。
{
path: '/about',
name: 'About',
meta:{
isLogin:true
},
component: () => import('../views/About.vue')
}
- 第二步:后台生成 token。在mock文件中创建一个 config.js 并配置
module.exports = {
jwtSecret:"somesecrtekeyforjsonwebtoken"
//真实项目中是后台负责的
}
- 第三步:后台配置路由。后台安装 npm i --save jsonwebtoken 并且在router.js 中配置
const config = require("./config");
const jwt = require("jsonwebtoken");
//生成token
const token = jwt.sign({
username: username,
password: password
}, config.jwtSecret);
res.send({
...
token:token,
username:username
})
- 第四步:此时前台浏览器就能打印拿到token,然后将它保存到本地,
修改Login组件:
<template>
<div>
<div v-if="token_username.length <= 0">
<input placeholder="用户名" type="text" v-model="username" />
<input placeholder="密码" type="text" v-model="password" />
<button @click="loginHandle">登陆</button>
</div>
<div v-else>
{{ token_username }}
</div>
</div>
</template>
<script>
export default {
name: "Login",
data() {
return {
username: "",
password: "",
token_username:""
};
},
created(){
if(localStorage.getItem("token")){
this.token_username = localStorage.getItem("username");
}
},
methods: {
loginHandle() {
// 登陆流程
this.$api.getLogin({
username: this.username,
password: this.password
}).then(res => {
if(res.data.code == 400){
alert("用户名密码错误");
}else{
this.token_username = res.data.username;
localStorage.setItem("token", res.data.token);
localStorage.setItem("username",res.data.username)
}
});
},
logoutHandle(){
localStorage.removeItem("token");
localStorage.removeItem("username");
this.token_username = ""; //让页面刷新
this.$router.push("/login");
}
}
};
</script>
- 第五步:前台路由就可以读取token值了,编辑
router.beforeEach((to,from,next) =>{
if(to.meta.isLogin){
// token:令牌
var token = localStorage.getItem("token");
if(token){
next();
}else{
next({
path:"/login"
})
}
}else{
next();
}
})
实现登录服务器端验证部分
- 第一步:新创建一个mysql数据库,创建表,插入数据:username : joe和password : 8888。
- 第二步:打开后台终端安装数据库 npm i --save mysql
- 第三步:在 mock 文件夹下创建一个 SQLConnect.js 文件用来连接数据库
const mysql = require("mysql");
const MySQLObj = {
host:"localhost",
user:"root",
password:"",
database:"web1910" //库名
}
const client = mysql.createConnection(MySQLObj);
function SQLConnect(sql,arr,callback){
client.query(sql,arr,(error,result)=>{
if(error){
console.log(error);
return;
}
callback(result);
})
}
module.exports = SQLConnect;
- 后台路由引入并且配置
const SQLConnect = require("./SQLConnect");
const sql = "select * from user where username=? and password=?";
const arr = [username, password];
SQLConnect(sql, arr, result => {
if (result.length > 0) {
const token = jwt.sign({
username: username,
password: password
}, config.jwtSecret);
res.send({
msg: "登陆成功",
code: 200,
token: token,
username: username
})
} else {
res.send({
msg: "登陆失败",
code: 400
})
}
})
- 成功实现登录验证。当点击 About 页面时,验证用户是否登录,如果登录则进入 About 页面;如果没有登录则跳转到 Login 登录页面。在 Login 页面用户输入账号密码点击登录时,再次验证输入的账号密码是否正确,如果正确则进入到 Login 页面,此时可以被允许进入 About 页面了;如果账号或者密码错误则显示提示消息。当点击 退出登录 按钮时,清除存储在本地 localStorage 里边的数据,并且通过将存储的用户名更改为空字符串来实现页面刷新的效果 this.token_username = " "; 通过 this.$router.push("/login") 回到初始化的 Login 登录页面
- 下面附上部分文件完整的代码
//mock后台路由router.js文件
const express = require("express");
const router = express.Router();
const config = require("./config");
const jwt = require("jsonwebtoken");
const SQLConnect = require("./SQLConnect");
router.post("/login", (req, res) => {
const username = req.body.username;
const password = req.body.password;
const sql = "select * from user where username=? and password=?";
const arr = [username, password];
SQLConnect(sql, arr, result => {
if (result.length > 0) {
const token = jwt.sign({
username: username,
password: password
}, config.jwtSecret);
res.send({
msg: "登陆成功",
code: 200,
token: token,
username: username
})
} else {
res.send({
msg: "登陆失败",
code: 400
})
}
})
})
module.exports = router;
//src文件下前端路由router.js文件
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Login from "../views/Login"
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path:"/login",
component:Login
},
{
path: '/about',
name: 'About',
meta:{
isLogin:true
},
component: () => import('../views/About.vue')
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
router.beforeEach((to,from,next) =>{
if(to.meta.isLogin){
// token:令牌
var token = localStorage.getItem("token");
if(token){
next();
}else{
next({
path:"/login"
})
}
}else{
next();
}
})
export default router
更多推荐
已为社区贡献1条内容
所有评论(0)