当前位置: 首页 > news >正文

01用户登录,登出,token等框架说明

01.cookie 设置

src/utils/auth.js

  • 首先要安装 cookies 插件
npm i cookies
  • 代码 11 和 26 行,设置了失效 7 天;
  • 代码 4 和 19 行,key 是可以自定义的;
import Cookies from 'js-cookie'

// token key
const TokenKey = 'mine_token';
// 获取 token
export function getToken() {
  return Cookies.get(TokenKey)
}
// 设置 token,expires 7 天有效
export function setToken(token) {
  return Cookies.set(TokenKey, token, {expires: 7})
}
// 删除 token
export function removeToken() {
  return Cookies.remove(TokenKey)
}

// 用户 key
const UserKey = 'mine_user';
// 获取 
export function getUser() {
  return Cookies.get(UserKey)
}
// 设置 
export function setUser(user) {
  return Cookies.set(UserKey, user, {expires: 7})
}
// 删除 
export function removeUser() {
  return Cookies.remove(UserKey)
}

02.axios 拦截设置

前提要先设置全局 API,在文件 .env.development.env.production

# base api
VUE_APP_BASE_API = 'http://192.168.182.13:8088'

src/utils/request.js

  • 代码 9 行,header 中的 token 不一定要 replace 替换。根据返回的token 字符串而定;
  • 代码 9 和 17 行是否重新设置,有冲突。江西矿山只设置了 20,也没影响;
  • 代码 9 和 16 行,getToken 方法获取 token 有可能为空 或 7 天到期失效。详见 src/utils/auth.js
import axios from 'axios'
import { Message } from 'element-ui'
import router from '@/router'
import { getToken } from '@/utils/auth'

// 新建 axios
const service = axios.create({
	baseURL: process.env.VUE_APP_BASE_API,
	// headers: { 'Authorization': getToken().replace('%20', ' ') } // 设置请求头
	timeout: 5000
})

// request 请求前拦截
service.interceptors.request.use(
	config => {
		if (getToken()) {// 测试,这里是否添加
			config.headers['X-Token'] = token;
		}
		return config
	},
	error => {
		return Promise.reject(error)
	}
)

// response 响应拦截
service.interceptors.response.use(
	response => {
		const res = response.data
		if(res.code == 401){
			Message({
				message: '身份验证过期,请登录',
				type: 'warning',
				duration: 5 * 1000
			})
			router.push('/')
		}
		return res
	},
	error => {
		if (401 === error.response.status) {
			Message({
			message: '身份验证过期,请登录',
			type: 'warning',
			duration: 5 * 1000
			});
			// 这里有可能是 '/' 或 '/login'
			router.push('/');
		} else {
			console.log('err' + error) // for debug
			Message({
				message: error.message,
				type: 'error',
				duration: 5 * 1000
			})
		}
		return Promise.reject(error)
	}
)

export default service

03.用户 API

src/api/user.js

  • 注意如下 url 或请求方式 getpost以具体的接口而定
  • 可能有 登录、获取用户信息、登出等;
import request from '@/utils/request'

// 获取用户信息
export function getInfo(id) {
	return request({
		url: `/mapgis/gm/v1/user/${id}/info`,
		method: 'get'
	})
}

// 登出
export function logout() {
	return request({
		url: '/vue-admin-template/user/logout',
		method: 'get'
	})
}

04.VueX user

src/store/modules/user.js

  • 代码 34 - 45 行,不是使用 axios 拦截,因为登录不需要;
import { getInfo } from '@/api/user'
import { getToken, setToken, removeToken, getUser, setUser, removeUser } from '@/utils/auth'

// 状态
const state =  {
    token: getToken(),
    name: getUser(),
    userId: '',// 可选项
    userRole: '',// 用户角色
    userInfo: null
}

// 同步设置
const mutations = {
    // token
    SET_TOKEN: (state, token) => {
        state.token = token;
    },
    // name
    SET_NAME: (state, name) => {
        state.name = name;
    },
    // 用户 id
    SET_USERID: (state, userId) => {
        state.userId = userId;
    },
    // 用户 角色
    SET_USERROLE: (state, userRole) => {
        state.userRole = userRole;
    },
    // 用户 信息对象
    SET_USERINFO: (state, userInfo) => {
        state.userInfo = userInfo;
    }
}

// 异步设置
const actions = {
    // 登录
    login({ commit }, userInfo) {
        const { form, axios } = userInfo;
        return new Promise((resolve, reject) => {
            let url = '/v1/auth/login';
            axios.post(url, form).then((resp) => {
                if (resp.data.succ) {
                    let obj = resp.data.obj;
                    setToken(obj.token);//设置 token cookie
                    setUser(form.user);//设置用户名 user cookie
                    commit('SET_TOKEN', obj.token);//设置token
                    commit('SET_NAME', form.user);//设置用户名
                    resolve();
                } else {
                    reject(resp)
                }
            });
        })
    },
    // 获取用户信息
    getInfo({ commit, state }) {
        return new Promise((resolve, reject) => {
            getInfo(state.token).then(response => {
                if(resp.succ) {
                    let info = resp.obj;
                    commit('SET_USERID', info.uid)
                    commit('SET_USERROLE', info.roleNames[0])
                    commit('SET_USERINFO', info)
                    resolve();
                } else {
                    reject(resp)
                }
            }).catch(error => {
                reject(error)
            })
        })
    },
    // 登出
    logout({ commit, state }) {
        // 删除 cookie
        removeToken();
        removeUser();
        // 删除信息
        commit('SET_TOKEN', '');
        commit('SET_NAME', '');
        commit('SET_USERID', '');
    }
}

export default {
    namespaced: true,
    state,
    mutations,
    actions
}

05.路由前置守卫

src/router/index.js

  • 引入 cookie
import { getToken } from '@/utils/auth'
  • 此处使用全局前置守卫,如果是单个页验证可参考 路由独享的守卫;
  • 如果项目还在开发阶段,暂不使用权限验证,可直接屏蔽如下代码;
router.beforeEach((to, from, next) => {
    //判断是否已登录
    if (!getToken() && to.name !== 'login') {
		//跳转到登录页
		next({ path: '/login' })
    } else {
      	next()
    }
})

06.登录/登出

登录

  • 先安装插件 js-base64

    npm i js-base64
    
  • 或 有的可以使用插件 js-md5

    npm i js-md5
    
  • 在登录页引入;

    import { encode } from 'js-base64';
    // 或
    import md5 from 'js-md5'
    
  • src/store/user.js异步方法 user/login

    • 代码 中的 inputNameinputPwform等参数根据当前页的设置而定;
    • 代码 11 行,路由有可能是 /login
    • 如果登录比较严,如有验证码、30分钟未操作要登出。可参考中山项目;
commit () {
	if (this.inputName.trim() == '' || this.inputPw.trim() == '') {
		this.$message({ type: 'error', message: '请输入用户名密码或验证码!' })
		return
	}
	let form = {
		"user": this.inputName,
		"pwd": md5(this.inputPw),
		"againPwd": md5(this.inputPw),
		"needPhoneAuth": false,
		"needEmailAuth": false
	}
	this.$store.dispatch('user/login', { form, axios: this.$axios }).then(data => {
		this.$router.push('/');
	}).catch((error) => {
		console.error('登录失败', error);
		this.$message({ type: 'error', message: '登录失败' })
	}) 
}

登出

this.$store.dispatch('user/logout');

07.TopHeader

进入主页,显示用户名可设置计算属性 userName参考第三篇《03用户及切换列表》

computed: {
    userName() {
        return this.$store.state.user.name
    }
}

相关文章:

  • 几位阿里发布这份内部MySQL性能优化法则笔记
  • java-php-python-ssm巢院小区疫情管控系统计算机毕业设计
  • Linux基础 - 系统安全(SELinux与Firewalld)
  • 学完这份“顶级”SpringCloudAlibaba笔记,微服务竟如此简单
  • Spring注解驱动开发及源码解析
  • 2.1RDB、AOF及混合持久化详解Redis持久化
  • matlab基于PID反馈的主动隔振效果仿真分析
  • 力扣记录:Hot100(8)——253-322
  • 模板 cdq分治解三维偏序
  • C++/Qt音视频通话开发MetaRTC源码解读,coturn穿透stun的使用
  • Spring读取配置文件
  • MySQL进阶第八天——innodb引擎
  • Easy Yapi插件使用详情
  • 迪士尼这部影片让我看到了AR观影的未来
  • FPGA学习笔记(二)Verilog初步入门
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • 10个确保微服务与容器安全的最佳实践
  • AHK 中 = 和 == 等比较运算符的用法
  • javascript 哈希表
  • JAVA多线程机制解析-volatilesynchronized
  • vue2.0开发聊天程序(四) 完整体验一次Vue开发(下)
  • 如何用vue打造一个移动端音乐播放器
  • 如何在GitHub上创建个人博客
  • 使用docker-compose进行多节点部署
  • 事件委托的小应用
  • 数据仓库的几种建模方法
  • 一个SAP顾问在美国的这些年
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  •  一套莫尔斯电报听写、翻译系统
  • 一些基于React、Vue、Node.js、MongoDB技术栈的实践项目
  • Salesforce和SAP Netweaver里数据库表的元数据设计
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • ​DB-Engines 11月数据库排名:PostgreSQL坐稳同期涨幅榜冠军宝座
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (C)一些题4
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (SpringBoot)第七章:SpringBoot日志文件
  • (windows2012共享文件夹和防火墙设置
  • (六)vue-router+UI组件库
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (五)IO流之ByteArrayInput/OutputStream
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • (转)http协议
  • (转)jdk与jre的区别
  • .gitignore文件设置了忽略但不生效
  • .net core 6 集成和使用 mongodb
  • .net 调用php,php 调用.net com组件 --
  • .NET6 命令行启动及发布单个Exe文件
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .Net环境下的缓存技术介绍
  • .NET设计模式(8):适配器模式(Adapter Pattern)
  • @JSONField或@JsonProperty注解使用
  • [ 蓝桥杯Web真题 ]-布局切换