前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用户登录的步骤你知道吗

用户登录的步骤你知道吗

作者头像
zhouzhouya
发布2023-10-26 17:29:46
2350
发布2023-10-26 17:29:46
举报
文章被收录于专栏:一名前端开发一名前端开发

实现登陆的思路:

1.前端将用户名和密码调用接口传给后端。 2.后端收到请求,验证用户名和密码是否正确,验证成功,返回一个token。 3.前端拿到token后,存储到localStorage和vuex中,并进行页面跳转。 4.前端每次跳转路由,都要判断localStroage有无token,没有则跳转登录页,有则跳转至对应路由页。 5.每次调用后端接口,都要在请求头中携带token。 6.后端判断请求头中有无token并验证,验证成功则返回数据,验证失败或没有token则返回401。 7.如果前端拿到401的状态码,则清空token信息并跳转登录页。

安装vuex

npm install vuex // 安装vuex 建立store文件夹,创建index.js文件此时vuex里面主要存储token的相关信息,代码如下:

代码语言:javascript
复制
import { createStore } from "vuex";
// 用Vuex.Store对象用来记录token
const store = createStore({
 
  state: {
    // 存储token
    token:"",
    userName:"" ,// 可选
    passWord:""
  },
  getters: {
	getToken(state){
		return state.token || localStorage.getItem("token") || "";
	}
  },
  mutations: {
    // 修改token,并将token存入localStorage
    setToken(state,token) {
      state.token = token;
      console.log('state.token: ', state.token);
      localStorage.setItem('token', token);
      console.log('store、localstorage保存token成功!');
    },
    delToken(state) {
      state.token = "";
      localStorage.removeItem("token");
    },
    // 可选
    setUserInfo(state, userName) {
      state.userName = userName;
    }
  },
 
 actions: {
   // removeToken: (context) => {
     // context.commit('setToken')
   // }
 },
});
  
export default store;

在main.js中引用

代码语言:javascript
复制
import store from './store'

封装axios

npm install axios; // 安装axios 创建network文件夹,再创建request.js文件. 在封装axios时,使用QS插件,增加一些安全性的查询字符串解析和序列化字符串的库。 安装npm install qs,在request.js文件中引用,import qs from 'qs';

代码语言:javascript
复制
/*
 * @LastEditors: zhouyanhong
 * @Description: ...
 * @Date: 2023-01-14 16:28:07
 * @LastEditTime: 2023-01-15 10:10:30
 * @Author: zhouyanhong
 */
import qs from 'qs'

import axios from 'axios'

import store from '../store/index'
import { ElMessage } from 'element-plus'
import router from '../router/index'

// 使用自定义的配置文件发送请求
const instance = axios.create({
    baseURL: '',
    timeout: 80000,
    headers: {
        // 'Content-Type': 'application/json;charset=UTF-8',
        // 'custome-header':'tianliangjiaoyu'
    }
})


// post请求的时候,我们需要加上一个请求头,所以可以在这里进行一个默认的设置,即设置post的请求头为
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';

// 添加请求拦截器
instance.interceptors.request.use(function (config) {
    // 每次发送请求之前判断vuex中是否存在token        
    // 如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况
    // 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断 
    const token = store.getters.getToken;
    console.log('token: ', token);
    if (token) {
        // 已经登录成功,统一添加token
        config.headers.Authorization = `Bearer ${token}`
    }
    // token && (config.headers.Authorization = token);
    return config;
}, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);

})


instance.interceptors.response.use(function (response) {
    if (response.status === 200) {
        return Promise.resolve(response);
    } else {
        return Promise.reject(response);
    }
}, function (error) {
    // 对响应错误做点什么
    if (error.response.status) {
        switch (error.response.status) {
            // 401: 未登录
            // 未登录则跳转登录页面,并携带当前页面的路径
            // 在登录成功后返回当前页面,这一步需要在登录页操作。                
            case 401:
                router.replace({
                    path: '/login',
                    query: {
                        redirect: router.currentRoute.fullPath
                    }
                });
                break;
            // 403 token过期
            // 登录过期对用户进行提示
            // 清除本地token和清空vuex中token对象
            // 跳转登录页面                
            case 403:
                ElMessage({
                    message: '登录过期,请重新登录',
                    duration: 1000,
                    type: 'success'
                });
                // 清除token
                localStorage.removeItem('token');
                store.commit('loginSuccess', null);
                // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面 
                setTimeout(() => {
                    router.replace({
                        path: '/login',
                        query: {
                            redirect: router.currentRoute.fullPath
                        }
                    });
                }, 1000);
                break;

            // 404请求不存在
            case 404:
                ElMessage({
                    message: '网络请求不存在',
                    duration: 1500,
                    type: 'success'

                });
                break;
            // 其他错误,直接抛出错误提示
            default:
                ElMessage({
                    message: error.response.data.message,
                    duration: 1500,
                    type: 'success'

                });
        }
        return Promise.reject(error.response);
    }
});



//封装对应的方法

const $get = (url, params) => {
    return new Promise((resolve, reject) => {
        axios.get(url, {
            params: params,
        })
            .then(res => {
                resolve(res.data);
            })
            .catch(err => {
                reject(err.data)
            })
    });
}
/** 
* post方法,对应post请求 
* @param {String} url [请求的url地址] 
* @param {Object} params [请求时携带的参数] 
*/
const $post = (url, params) => {
    return new Promise((resolve, reject) => {
        axios.post(url, qs.stringify(params)) //是将对象 序列化成URL的形式,以&进行拼接   
            .then(res => {
                resolve(res.data);
            })
            .catch(err => {
                reject(err.data)
            })
    });
}
//下面是vue3必须加的,vue2不需要,只需要暴露出去get,post方法就可以
export default {
    install: (app) => {
        app.config.globalProperties['$get'] = $get;
        app.config.globalProperties['$post'] = $post;
        app.config.globalProperties['$axios'] = axios;
    }
}

此时需要理解一下如何封装axios, 1.添加请求拦截器,发送请求之前判断是否存在token,如果存在统一在http的请求中加上token 2.添加响应拦截器,如果响应成功,调用promise.resolve(),响应失败根据不同的状态码做出不同的处理结果。401:未登录,没权限访问。403:登录过期。404:请求不存在。 3.封装get,post,put,delete等请求方法

封装vue-router

重难点:实现动态添加路由 公共的路由,每个用户都可以访问的

代码语言:javascript
复制
import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
  history: createWebHashHistory(), // hash模式:createWebHashHistory,history模式:createWebHistory
  routes: [
    {
      path: "/",
      name: "Home",
      component: () => import("@/views/Home"),
    },
    {
      path: "/home",
      name: "Home",
      component: () => import("@/views/Home"),
    },
    {
      path: "/404",
      name: "404",
      component: () => import("@/views/404"),
    },
    {
      path: "/notAllow",
      name: "notAllow",
      component: () => import("@/views/notAllow"),
    },
    {
      path: "/login",
      name: "Login",
      component: () => import("@/views/Login"),
      meta: {
        noLogin: true, //无须登录即可浏览
      },
    },
  ]
})
export default router

登录进去时有一些路由是所有人可见,设置为默认路由。 在进行路由跳转时,设置路由守卫,在进页面之前,判断有token,才进入页面,否则返回登录页面。 通过asyncRoutestMark判断路由是否有过拼接,然后循环navigationList(模拟接口返回数据),通过router.addRoute向数据组添加数据,通过router.getRoutes()存储路由,并放在vuex中。

代码语言:javascript
复制
router.beforeEach((to, from, next) => {
  const isLogin = localStorage.token ? true : false
  console.log('isLogin: ', isLogin);
  console.log("navigationList", navigationList)
  console.log("11111111111111", store.state.asyncRoutestMark)
  if (isLogin) {
    if (!store.state.asyncRoutestMark) {
      navigationList.forEach(navigation => {
        router.addRoute('home', {
          path: navigation.url,
          meta: { name: navigation.name, isAsync: true, icon: navigation.icon },
          name: navigation.url,
          component: () => import(`../views/${navigation.url}`)
        })
      })
      console.log(router.getRoutes(), '查看现有路由')
      console.log("to",to)
      store.commit('changeRouter', true)
      store.commit("setAllRoutes",router.getRoutes())
      next({ ...to, replace: true })  
    }else {
      next()
    }
  }else {
    next()
  }
})
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-10-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实现登陆的思路:
    • 安装vuex
      • 封装axios
        • 封装vue-router
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档