登录注册完整流程

开发场景描述:
当准备从零开始做一个项目时,此时前后台同时开发,由于后台可能会由于时间问题不能提供数据,此时就需要前端人员模拟数据,例如Mock。在外面的Vue中,同样可以实现mock的操作模拟数据。
需要对 JWT (Json Web Token) 和 token 有一定认知。
· 首先打开Apache 和 MySQL

实现登录部分

  1. 第一步 :搭建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>
  1. 第二步 :将Login引入路由并配置
  2. 第三步:用 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;
  1. 先用 postman 测试,这样容易分别是前端出错还是后台出错,如果可以获取成功后执行下一步
  2. 回到前台,创建 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;
  1. 解决跨域问题:在项目根目录下创建一个vue.config.js配置文件并设置配置项:
//vue.config.js文件
module.exports = {
    devServer:{
        proxy:{
            "/api":{
                target:"http://localhost:3000/",
                pathRewrite:{  //重写路径
                    "^/api":""
                },
                changeOrigin:true  //允许跨域
            }
        }
    }
}
  1. 在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)

  1. 第一步:给 about组件设置路由元信息。
{
    path: '/about',
    name: 'About',
    meta:{
      isLogin:true
    },
    component: () => import('../views/About.vue')
 }
  1. 第二步:后台生成 token。在mock文件中创建一个 config.js 并配置
module.exports = {
    jwtSecret:"somesecrtekeyforjsonwebtoken"  
    //真实项目中是后台负责的
}
  1. 第三步:后台配置路由。后台安装 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
	})
  1. 第四步:此时前台浏览器就能打印拿到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>
  1. 第五步:前台路由就可以读取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();
  }
})

实现登录服务器端验证部分

  1. 第一步:新创建一个mysql数据库,创建表,插入数据:username : joe和password : 8888。
  2. 第二步:打开后台终端安装数据库 npm i --save mysql
  3. 第三步:在 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;
  1. 后台路由引入并且配置
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
            })
        }
    })
  1. 成功实现登录验证。当点击 About 页面时,验证用户是否登录,如果登录则进入 About 页面;如果没有登录则跳转到 Login 登录页面。在 Login 页面用户输入账号密码点击登录时,再次验证输入的账号密码是否正确,如果正确则进入到 Login 页面,此时可以被允许进入 About 页面了;如果账号或者密码错误则显示提示消息。当点击 退出登录 按钮时,清除存储在本地 localStorage 里边的数据,并且通过将存储的用户名更改为空字符串来实现页面刷新的效果 this.token_username = " "; 通过 this.$router.push("/login") 回到初始化的 Login 登录页面
  2. 下面附上部分文件完整的代码
//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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值