跳到主要内容

设计

版权声明
  • 控制外部请求的守门人
  • 对用户进行认证,对操作进行鉴权,通过状态机驱动资源访问
  • 动态生成用户的 Web 端页面,并通过 Nop Xpl 生成 index.html 以便于注入真实的平台名称平台 Logo等待动画等定制内容
    • 通过 Nop 的 precompile 机制,调用 npm 对页面渲染引擎进行构建, 并将构建产物复制到 src/main/resources/META-INF/resources 目录下
  • 拆分为 apiweb 两类网关以独立进行开发,并可按需引入
客户端客户端Gateway 服务Gateway 服务API 服务API 服务[001]请求 API附带 JWT[002]解码 JWT 获取用户信息[003]获取用户权限列表[004]编码用户信息及其权限列表,并放在请求头中[005]通过内置的服务通信证书加密 API 请求[006]发起 API 调用请求[007]通过内置的服务通信证书解密 API 请求[008]从请求中获取用户权限列表[009]根据用户权限列表检查是否对请求 API 有访问权限[010]调用 API 对应函数[011]根据用户权限列表做数据查询控制[012]执行业务逻辑[013]返回调用结果[014]通过内置的服务通信证书加密处理结果[015]返回处理结果[016]解密响应数据[017]返回调用结果

状态机驱动

根据各类状态数据来驱动系统的业务逻辑流转,并提供对状态机的可视化设计支持。

  • 在多租户模式下,以多租户标识为 Delta 层,再在该层内定制状态驱动 DSL
  • 采用 Nop Task 机制进行实现

上下文

Contexttenant = "xxxx"user = "xxxx"accessToken = "xxxx"traceId = "xxx"lang = "zh_CN"页面语言locale = "en_US"timezone = "+08"所处地区

资源访问

前端站点(site)也属于资源(resource)。

返回待访问资源显示错误信息提示用户无权限、资源不存在等信息,由前端站点的布局页面统一展示和处理错误信息。若访问的是接口,则在状态码和响应中附加错误信息进入 [登录] 站点登录失败时,提示“帐号密码错误”等信息[所访问资源已存在][所访问资源不存在][所访问资源可匿名][所访问资源不可匿名][未登录][登录失败][登录成功][已登录][有权限访问该站点][无权限访问该站点]

该状态机用于控制所有的资源访问动作,其流转过程中由 用户登录状态(是否登录)和 资源可访问状态(是否存在、用户是否有权限)确定后续逻辑, 并通过 链接跳转 驱动该状态机(没有链接跳转就无法驱动状态变化)。

接口调用返回状态码和 JSON 响应数据,在响应数据中会包含错误码、错误信息、跳转地址等, 由前端根据状态码和响应数据判断后续操作。

对前端站点 url 的请求返回的都是页面渲染引擎代码, 其具体的页面结构需单独再发送一次资源请求才能获取到, 所以,以上状态机控制的是资源请求接口,对 js、css 等静态资源不做控制。

API 网关

  • 在页面设计时,在引用的 API 中需以参数或 Header 形式附加目标服务标识, 该标识仅对 API 网关有效,目标服务会直接忽略
  • 在微服务环境下,API 网关会根据服务标识,路由 API 到目标服务; 在单体环境下,则无需任何处理
  • 需要通过设计 api 模型生成 RPC 代码?

Web 资源网关

  • 以站点做为前端资源组织结构的最顶层模型
    • 一个平台(Platform)可包含一个或多个应用(Application), 每个应用可包含多个前端站点(site), 每个前端站点可包含一个或多个资源(resource), 每个资源可对应至多一个页面(page), 每个页面可包含一个或多个操作(action), 每个操作涉及一个或多个接口(api
    • 每个站点、资源、操作和接口均根据用户权限(permission)做访问控制
    • 一个前端站点面对的是一类用户或某个场景, 比如,用户登录、后台管理、门户等,均为不同的前端站点
    • 所有前端站点都需要做用户鉴权,不需要登录的前端站点, 实际上是授权给了匿名用户,每个匿名用户也同样都有 Access Token
      • 同一平台的多个应用之间可共享用户认证数据, 所以,已认证用户可直接在多个应用之间无缝跳转,仅需要认证一次
  • 提供前端资源的获取接口,返回各用户可访问的前端站点的 JSON 结构数据
    • 所有前端站点均采用 DSL 定义和生成,并根据用户权限动态增减可访问内容
    • 在开发阶段,在页面、资源、操作等结构数据中需包含其 DSL 定义的位置信息, 以便于直接调试定位
    • 对打包到 jar 中的前端资源文件可以采用 Nop vfs 机制做文件的分层替换, 以支持对前端资源文件的定制化修改
  • 需强制设置默认站点页面,用于处理对未定义站点的 url 访问

Site DSL

本平台针对的是动态的资源授权机制,不存在拥有固定权限的角色,无法在 DSL 中配置固定数据。

<web>
<site id="common" x:abstract="true"
title="渡舟平台" runInEnv="development"
logo="/logo.svg" locale="zh">
<layout bgColor="#fff" spinner="/loading.svg"
html="/path/to/app.site-html.xml"
>
<scripts>
<!-- 入口脚本放在最开始位置 -->
<script name="renderer" url="/js/renderer-amis-0.1.0.js" />
<script name="engine" url="/js/amis/sdk-6.0.0.js" />
</scripts>

<styles>
<style name="engine" url="/css/amis/theme.css" />
<style name="renderer" url="/css/renderer-amis-0.1.0.css" />
</styles>
</layout>
</site>

<!-- 默认站点,匹配所有未匹配的站点,用于返回 404 页面 -->
<site id="default" url="*">
</site>

<!-- 登录 - Sign In;注册 - Sign Up;登出 - Sign Out -->
<site id="signin" x:prototype="common"
subTitle="用户登录"
url="/signin">
<resources>
<resource id="user-signin"
url="/path/to/signin.page.xml">
</resource>
</resources>

<layout>
<config><![CDATA[
return {
data: {},
schemaApi: site.getResource('signin').url
};
]]></config>
</layout>
</site>

<site id="main" x:prototype="common"
subTitle="门户"
url="/">
<resources>
<resource id="news"
displayName="新闻"
url="/path/to/news.page.xml">
</resource>
<resource id="blog"
displayName="博客"
url="/path/to/blog.page.xml">
</resource>
<resource id="admin"
displayName="后台管理"
url="redirect:/admin">
</resource>
</resources>
</site>

<site id="admin" x:prototype="common"
subTitle="后台管理"
url="/admin">
<resources>
<resource id="auth"
displayName="权限管理"
url="/path/to/auth.page.xml">
</resource>
<resource id="organization"
displayName="组织管理"
url="/path/to/org.page.xml">
</resource>
</resources>
</site>
</web>
  • site 属性列表

从前端开发的角度来看,一个 site 实际上就是一个单页面应用

属性名属性说明备注

id

前端站点唯一标识

需在同一个服务内保持唯一性

url

前端站点的访问地址,其路径相对于应用的 url

若为 * 则匹配已定义站点之外的站点

runInEnv

所处的运行环境

用于在前端显示开发状态信息、开启调试等,可选值为:

  • development:开发环境
  • staging:阶段构建环境
  • testing:测试环境
  • production:生产环境

若未设置值,则视为 development

title

前端站点主标题

subTitle

前端站点副标题

locale

多语言环境下的当前语言

logo

前端站点 Logo 图片

资源文件相对于根站点的路径

layout

前端站点的布局器

用于指定布局相关的 js 脚本和 css 样式。 布局可拆分为上下左右等多个部分以共用, 并提供错误信息的统一处理方式(弹窗或整页显示)

layout.bgColor

背景色

前端站点的 body 背景色,默认为 #fff

layout.spinner

载入动画图片

资源文件相对于根站点的路径

layout.html

站点入口 HTML 页面的 DSL 定义文件路径

在其 xpl 脚本中可通过全局变量 $site 引用当前站点的模型对象

layout.scripts.script

布局器相关的 js 地址

指定 name 可便于定制化重载。第一个脚本为主脚本,其余的为依赖脚本。 注:声明顺序为其加载顺序

layout.styles.style

布局器相关的 css 地址

指定 name 可便于定制化重载。注:声明顺序为其加载顺序

layout.config

布局器的配置数据生成函数

在函数内可访问当前站点变量 site,并构造返回 JSON 布局结构数据(具体结构由渲染器确定)

  • site.resources.resource 属性列表

资源一般为导航菜单,具体的表现形式由 site.layout 确定。

属性名属性说明备注

id

资源的唯一标识

任意层级的资源均需在同一个前端站点内保持唯一性

url

资源的页面 DSL 路径

@redirect: 开头的,将视为外部资源,在访问时直接跳转

displayName

资源名称

一般作为导航菜单名称

icon

图标 css 类名