2.vue-element-admin登陆验证

    技术2024-11-04  22

    目录

    1.综述

    2.登陆验证

    3.代码实现

    (1)数据库的结构

    (2)后台接口函数

    (3)前台js函数

    4.Github地址


    1.综述

    在搭建完aiohhtp后台之后,就可以前台页面的搭建了,我选用的是vue-element-admin,直接git下来之后使用npm安装完依赖就可以直接跑起来了,不过首先需要解决的就是登陆验证的问题,我这里只是说一下我的解决方法,并且还没有考虑到权限的问题,因为权限的问题比较复杂,我的这个项目还没做到,等做到了再给大家分享我的解决方法.

    2.登陆验证

    vue-element-admin的登陆验证做的还是很好的,我们首先要做的事弄明白它的验证过程,首先根据用户名和密码拉取用户的token信息,然后设置用户的cookie信息,之后在利用vue中全局钩子函数beforeEach对每一个即将跳转的路由进行验证,验证的逻辑为:

    (1)尝试获取用户的cookie信息,如果获取失败则跳转到登陆界面,如果获取成功则进行下面步骤

    (2)如果要进入的路由为login,则直接跳转到登陆界面,否则尝试获取store中的用户名称name,如果获取成功则跳转,否则尝试根据token拉取用户的信息,如果拉取成功则跳转,否则清除用户的token并跳转到登陆界面.

    (3)用户退出:直接调用logout清除用户的token

    综上,在了解了验证过程之后,由于vue-element-admin中使用的都是mock的假数据,我们只需要将对应的接口改成我们自己的后台接口即可

    3.代码实现

    下面是我的代码实现,仅供大家参考

    (1)数据库的结构

    分别有User_cfg(用户配置),role_cfg(权限配置)以及user_view(用户视图)两个表和一个视图,创建的SQL语句如下

    /* 1.role_cfg: 用户角色配置 role_id: 角色ID role_name: 角色名称 role_description: 角色描述 */ CREATE TABLE `role_cfg` ( `id` int NOT NULL AUTO_INCREMENT, `role_id` int DEFAULT NULL, `role_name` varchar(5000) DEFAULT NULL, `role_description` varchar(5000) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /* 2.user_cfg: 用户配置 username: 用户名 password: 密码 role_id: 用户角色ID user_introduction: 用户简介 user_avatar: 用户头像 */ CREATE TABLE `user_cfg` ( `id` int NOT NULL AUTO_INCREMENT, `username` varchar(1000) DEFAULT NULL, `password` varchar(1000) DEFAULT NULL, `role_id` int DEFAULT NULL, `user_introduction` varchar(5000) DEFAULT NULL, `user_avatar` varchar(1000) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /* 3.user_view: 用户视图 */ select `user_cfg`.`id` AS `id`,`user_cfg`.`username` AS `username`,`user_cfg`.`password` AS `password`,`role_cfg`.`role_name` AS `role_name`,`role_cfg`.`role_description` AS `role_description`,`user_cfg`.`user_avatar` AS `user_avatar`,`user_cfg`.`user_introduction` AS `usertoken`,`user_cfg`.`role_id` AS `role_id` from (`role_cfg` join `user_cfg` on((`user_cfg`.`role_id` = `role_cfg`.`role_id`)))

    其中的每个字段的名称也很明显,至此和登陆以及用户相关的表和视图即创建完成

    (2)后台接口函数

    # 登陆界面的接口 @method_dec("/login") async def login(request): """用户登陆 `username`: 用户民 `password`: 密码 `return`: dict{code: int, msg: str, username: str, token: str, avatar: str} """ try: request_data = await request.json() username = request_data.get("username") # 获取用户名 password = request_data.get("password") # 获取密码 query_data = [{"usertoken": item.usertoken, "user_avatar": item.user_avatar, "password": item.password} for item in [User(*item) async for item in await db.get_data(f"select * from user_view where username='{username}'")]] if query_data[0]["password"] == password: return web.json_response({"msg": "登陆成功!", "code": 200, "name": username, "token": query_data[0]["usertoken"], "avatar": query_data[0]["user_avatar"]}) else: return web.json_response({"msg": "密码错误", "code": 500}) except (IndexError, Exception): import traceback return web.json_response({"msg": "用户名错误" + traceback.format_exc(), "code": 500}) @method_dec("/get_user_info", 'get') async def get_user_info(request): """根据token获取用户信息 `token`: 用户的token信息 `return`: dict{code: int, data: dict{name: str, token: str, avatar: str}} """ token = request.query.get("token") response_data = [{"usertoken": item.usertoken, "user_avatar": item.user_avatar, "password": item.password, "username": item.username} for item in [User(*item) async for item in await db.get_data(f"select * from user_view where usertoken='{token}'")]] return web.json_response({"data": {"name": response_data[0]["username"], "token": response_data[0]["usertoken"], "avatar": response_data[0]["user_avatar"]}, "code": 200}) @method_dec("/logout") def logout(request): """退出登录 `return`: dict{code: int, data: str} """ return web.json_response({ "code": 200, "data": "success" })

    (3)前台js函数

    在@/view/login/index中即为登陆界面的组件,登陆按钮对应的方法为handleLogin,我们只需要修改这个函数即可

    this.$refs.loginForm.validate(valid => { if (valid) { this.loading = true let userName = this.loginForm.username; let passWord = this.loginForm.password; let url = restFulUrl() + "/login"; let data = {}; data["username"] = userName; // 用户名 data["password"] = passWord // 密码 this.$axios.post(url, data).then(response => { this.$message({ message: response.data.msg, type: "success" }); if (response.data.msg === "登陆成功!") { this.$store.dispatch('user/login', response.data).then(() => { this.$store.dispatch('socket/connect') // 连接websocket this.$router.push({path: this.redirect || '/'}) this.loading = false }) } }) } else { console.log('error submit!!') return false } })

    这里需要注意的是原来的代码对用户名的输入也有验证,验证的函数在@/utils/validate中,我这里是直接将该函数的返回值改成了true。

    接口就可以去修改user/login中的接口了,所有的vuex状态管理都在store文件夹中,我们直接去@/store/modules/user.js中修改对象的接口函数即可,下面是我的修改方式可以供大家参考,我直接在这里设置了相关的字段,没有再根据token再去获取一次信息

    login({commit}, userInfo) { const {name} = userInfo return new Promise((resolve, reject) => { commit('SET_TOKEN', userInfo['token']); // 设置token commit('SET_NAME', userInfo['name']); // 设置name commit('SET_AVATAR', userInfo['avatar']); // 设置avatar const data = {name: userInfo['name'], avatar: userInfo['avatar']} setToken(userInfo['token']) // 设置cookie resolve(data) }) },

    之后再去修改一下getInfo以及logout两个函数中的接口ip,使之与我们上面写的web.py中相对应即可,以下是我的修改代码

    export function getInfo(token) { return request({ url: '/get_user_info', method: 'get', params: { token } } ) } export function logout() { return request({ url: '/logout', method: 'post' }) }

    效果图如下:

    至此,登陆的验证即完成.至于登录后侧边栏的设置以及前台websocket的使用可以参考我后面的文章

    4.Github地址

    https://github.com/JustKeepSilence/DownLoad,欢迎大家和我一起探讨交流~~~

    Processed: 0.012, SQL: 9