8月项目
昨日回顾:
- 只要看到登录表单,想到数据双向绑定
- vo层,返回对象类
- 对状态码的规定(业务状态码自定义,不要与网络状态码混淆)
- DigestUtils.md5DigestAsHex( )
- MD5相关概念 ,为了更安全加盐值,参考博客
文章目录
用户登录的实现
用户数据存储
业务说明
根据登录需求,后台返回SysResult对象,其中data表示token的记录
规则:一次请求,一次响应,当即不处理数据,之后无法再取到,服务器返回的响应数据应该采用一种特殊的方式保存
浏览器用于存储服务器数据的常用存储媒介
-
Session(常用)
在计算机中,尤其是在网络应用中,称为“会话控制”。Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web页时,如果该用户还没有会话,则Web服务器将自动创建一个 Session对象。当会话过期或被放弃后,服务器将终止该会话。Session 对象最常见的一个用法就是存储用户的首选项。例如,如果用户指明不喜欢查看图形,就可以将该信息存储在Session对象中。有关使用Session 对象的详细信息,请参阅“ASP应用程序”部分的“管理会话”。注意会话状态仅在支持cookie的浏览器中保留。会话控制
可以存储数据信息
生命周期整个会话,,在会话期间数据是有效的,如果会话窗口关闭则数据清除
存储在浏览器内存里(前端) -
Cookie
Cookie,有时也用其复数形式 Cookies。类型为“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息
文本文件
存储用户的登录信息(加密数据,更加安全)
保存到用户计算机的终端中,可以临时或永久存储信息
关于Session和Cookie的比较:
手机银行的用户登录信息:使用Session,Session安全性较高
购物网站要求用户7天免密登录?使用Cookie进行存储
公司财务信息 Session
总结: 如果对于数据的安全性要求较高使用session,如果存储一些大量查询的数据(不重要的)一般采用Cookie进行保存。
前端代码
let token = result.data
window.sessionStorage.setItem("token",token)
获取用户token信息,把它存储到Session中
调用浏览器中的Session机制,存储信息
如何查看:
chrome浏览器 -->Inspect --> application --> Session Storage
系统首页跳转
this.$router.push("/home")
编辑路由
import VueRouter from 'vue-router'
import Home from "../components/Home.vue"
Vue.use(VueRouter)
const routes=[{path:'home',component:Home}]
配置路由
const router= new VueRouter({
routes
})
路由导航守卫
如果用户没有登陆,不允许跳转其他页面,只允许访问login登录页面
实现方式
前端:路由导航守卫
单点登录策略 JWT相关知识
路由导航守卫的实现代码v1
router.beforeEach((to,from,next) =>{
if(to.path === '/login') return next()
let token = window.sessionStorage.getItem('token')
if(!token) return next('/login')
next()
})
路由导航守卫的实现代码v2
router.beforeEach((to,from,next) =>{
if(to.path === '/login') return next()
let token = window.sessionStorage.getItem('token')
if(token !=null && token.length >0) {
return next()
}else{
return next('/login')
}
})
beforeEach: 循环遍历
to 要跳转的网址
from 请求从哪里来
next 回调函数 放行、跳转
如果访问login 直接放行
菜单设计
查询层级分类菜单,使用parentid,而不使用level,因为level只表示层级,不知父类是谁
/*查询一级分类菜单*/
SELECT * FROM rights WHERE parent_id = 0 ;
/*查询二级商品分类信息,已知商品id=3*/
SELECT * FROM rights WHERE parent_id = 3 ;
编辑页面的JS
async getMenuList(){
const{ data: result} = await this.$http.get('/rights/getRightsList')
if(result.status !== 200) return this.$message.error("左侧菜单查询失败")
this.menuList = result.data
}
菜单需要获取2级菜单
2级信息封装到1级的children里
关于层级表设计的说明
业务关系: 1级 —— 2级 ——3级
想法1 :定义三张表
数据结构复杂,不便于扩展
想法2 : 定义一张表, id parent_id
每个ID都有自己的parent_id
如果有父子关系,一般采用parent_id进行封装
自关联的方式
POJO 说明
编辑rights的pojo
@TableName("rights")
@Data
@Accessors(chain=true)
public class Rights extends BasePojo{
@TableId(type =IdType.AUTO)
private Integer id;
private String name;
private Integer parentId;
private String path;
private Integer level;
@TableField(exist=false)
private List<Rights> children;
}
}
关于端口号的说明
8000端口:vue ui vue客户端管理器所占用的端口
8080 端口:前端脚手架项目启动时占用的端口号
8091端口:后台Spring Boot业务系统的端口号
左侧菜单的跳转
- 定义路由占位符,在home组件中,在中间定义了路由占位符
- 利用前端vue路由跳转机制,注意组件分块保留时,放在children里
- 菜单的路径path是自己定义在数据库中的