Skip to content

DTLE 项目(二):权限控制

dtle 项目的权限系统基于 RBAC,在系统中定义不同的角色,每个角色具有一组权限,而用户被分配到角色。通过控制用户角色的分配,可以实现对用户访问不同功能和资源的权限控制。权限控制包括两大部分:用户身份验证和资源授权。

dtle 用户身份验证使用了基于 token 的认证,用户登录后,后端会返回一个 token 给客户端,客户端将其放在本地存储中,每次发请求带上这个 token,服务端就可以验证用户身份,前端在 axios 的请求拦截器中添加对应的配置config.headers.Authorization,并在响应拦截器中对特定的状态码比如 403 或者 404 进行统一处理。

在资源授权方面,dtle 前端权限系统整体分三层:路由权限、菜单权限和操作权限。页面权限并不只是菜单权限,比如某个用户并没有 A 页面的访问权限,但他知道路径,即使看不到菜单,也能越权访问到 A 页面,所以我们需要路由权限。

在菜单权限和路由权限层级上,由前端维护一个固定的路由表,所有路由信息都写死在前端代码;而后端只返回权限配置信息,前端将二者进行对比,有权限就渲染路由,用户可以正常访问当前页面,无权限的则不渲染,这样即使用户知道路径也不能越权访问。

在操作权限层级上,最基本的思路是前端维护页面的按钮信息(按钮名称等),后端返回当前页面的操作权限。前端对这些权限信息进行统一处理合并,最终形成一个权限列表,前端将这个权限列表和本地的操作按钮信息进行对比,如果某个按钮没有权限则不渲染,这样既可以保证页面的操作权限,同时按钮渲染也很会更灵活。

我们的项目主要部署在客户的内网环境。在这种环境下,使用 HttpOnly Cookie 其实无法带来明显的额外安全收益:没有来自公网的跨站攻击来源,而且部分客户环境中并不提供 HTTPS,导致 Cookie 的 Secure、SameSite 等策略也无法充分发挥作用。

同时,项目前后端分离架构,前端页面和后端接口运行在不同的端口甚至不同子域下。如果改用 Cookie,就必须处理跨域这些配置,一旦配置不严谨就会导致 Cookie 不携带、用户无法登录等问题,维护成本很高。

相比之下,将 token 存在 localStorage 更符合我们的工程需求:登录态完全由前端显式控制;axios 拦截器可以统一注入 Authorization 头;登出时直接清除即可,不依赖浏览器的自动 Cookie 行为,逻辑预期可控稳定。

这是在安全性、可控性和工程复杂度之间做的权衡。在当下这个场景这并不是“不安全”,而是选择一个更适配当下业务环境的方案。