WeBASE实训插件方案

1 背景介绍

2020年7月6日,人社部联合国家市场监管总局、国家统计局向社会发布了第三批新职业名单,“区块链工程技术人员”赫然在列,越来越多的区块链从业者得到了国家层面的承认,对就业、创业的带动作用明显,彰显了区块链行业的巨大价值和就业前景。随着市场对人才的需求和要求迅速增长,区块链技术培训需求加快释放。如何将 WeBASE与区块链课程相结合,以更好的服务开发者?应对这一命题,WeBASE团队和FISCO BCOS 教育合作伙伴柏链教育对 WeBASE 功能进行针对性调整,推出WeBASE实训插件方案。

2 插件使用形态

WeBASE实训插件方案主要的目的是:将WeBASE管理台的部分功能作为插件嵌入到具体的实训系统中,辅助实训系统完成其区块链相关的一些实训功能。

  1. 其嵌入的形式可以入下图:![](../../images/WeBASE-Training-Plugin-Plan/iframe2.png)

../../_images/iframe1.png

3 具体改造方案

  1. 侧边栏默认收起
  2. 陆页面获取参数配置,根据配置判断是否支持iframe嵌入,允许哪些域名嵌入deploy
  3. 满足iframe嵌入的条件下,如果是iframe嵌入,则自动登录
  4. 自动登录的用户取消使用引导
  5. 自动登录的用户隐藏修改密码功能(包括首次登陆、右上角修改密码入口)
  6. 自动登录跳转到指定的router

4 使用方法和二次开发

4.1 安装 WeBASE 环境

使用到的子系统有WeBASE-Front、WeBASE-Node-Manager、WeBASE-Sign、 WeBASE-Web。WeBASE-Web使用dev-sx分支,WeBASE-Front、WeBASE-Node-Manager、WeBASE-Sign 使用v1.5.1及上版本。

4.2 WeBASE配置

4.2.1 WeBASE-Node-Manager数据库中插入参数设置数据,脚本如下:

  1. INSERT INTO `tb_config`(`config_name`, `config_type`, `config_value`, `create_time`, `modify_time`) VALUES ('SupportIframe', 2, '1', '2020-09-22 17:14:23', '2020-09-22 17:14:23');
  2. INSERT INTO `tb_config`(`config_name`, `config_type`, `config_value`, `create_time`, `modify_time`) VALUES ('IframeSupportHostList', 3, 'baidu.com|163.com', '2020-09-22 17:14:23', '2020-09-22 17:14:23');

其中,SupportIframe设置为1,表示开启iframe嵌入支持;IframeSupportHostList为iframe嵌入支持的host白名单列表。

配置访问接口如下:

  1. http://127.0.0.1:5001/WeBASE-Node-Manager/config/list?type=2

4.2.2 WeBASE-Node-Manager配置

修改webase-node-manager/conf/application.yml。

  • 修改constant.permitUrlArray:
  1. permitUrlArray: /account/login,/account/pictureCheckCode,/login,/user/privateKey/**,/config/encrypt,/config/version,/front/refresh,/api/*,/config/list
  • 修改constant.verificationCodeMaxAge,设置为与你的系统的session时间一致。
  • 修改constant.enableVerificationCode=false,设置为false,用以固定验证constant.verificationCodeValue=”8888”,为固定的验证码值,不需要修改
  • 修改constant.developerModeEnable,设置为true,开启开发者模式。
  • 重启WeBASE-Node-Manager服务。

这些配置主要的作用是:

  1. 开发者模式主要是为了做学员间的合约和私钥隔离。
  2. 固定校验码为了实现单点登录
  3. permitUrlArray配置是为了放开接口访问权限

5 实验台中使用

5.1 iframe嵌入

在适当的位置使用iframe嵌入,嵌入时直接使用WeBASE-Node-Manager的login页面。 如:

  1. <iframe
  2. ref="myFrame"
  3. src="http://localhost:3006/#/login"
  4. frameborder="0"
  5. width="100%"
  6. height="700"
  7. ></iframe>

5.2 自动登录

向子页面传递参数(router, user, password),实现自动登录。其中,用户的账号及密码,为WeBASE-Node-Manager平台已添加的账户信息,建议账户类型为开发者;router为指定跳转后定位到的页面

  1. router清单:
  2. /home 首页
  3. /contract 合约IDE
  4. /contractList 合约列表
  5. /cnsManagement CNS查询
  6. /CRUDServiceManagement CURD
  7. /privateKeyManagement 私钥管理

vue向webase子页面传参示例:

  1. <script>
  2. export default {
  3. data() {
  4. return {};
  5. },
  6. created() {},
  7. mounted() {
  8. this.iframeInit();
  9. },
  10. computed: {},
  11. methods: {
  12. iframeInit() {
  13. let myFrame = this.$refs["myFrame"];
  14. if (myFrame.attachEvent) {
  15. //兼容浏览器判断
  16. myFrame.attachEvent("onload", function () {
  17. let iframeWin = myFrame.contentWindow;
  18. iframeWin.postMessage(
  19. { router: "/contract", user: "admin", password: "123456" },
  20. "*"
  21. );
  22. //data传递的参数 *写成子页面的域名或者是ip
  23. });
  24. } else {
  25. myFrame.onload = function () {
  26. let iframeWin = myFrame.contentWindow;
  27. iframeWin.postMessage(
  28. { router: "/contract", user: "admin", password: "123456" },
  29. "*"
  30. );
  31. };
  32. }
  33. },
  34. },
  35. };
  36. </script>

在适当的位置使用iframe嵌入 嵌入示例

  1. <template>
  2. <div style="height:100%">
  3. <div>
  4. <div style="height:100%;width: 10%;float: left;background: #0B243B;">
  5. <div style="width: 100%;float: left;border-bottom:1px">
  6. <div style="padding-left: 35px;padding-top: 40px;">
  7. <span style="font-size: 14px;color: #37eef2;">学生</span>
  8. </div>
  9. </div>
  10. <div style="width: 100%;height:250px;float: left;">
  11. <div style="padding-top: 50px;padding-left: 60px;">
  12. <span style="font-size: 14px;color: #37eef2;text-align: left;">结束实验</span>
  13. </div>
  14. <div style="padding-top: 50px;padding-left: 60px;">
  15. <span style="font-size: 14px;color: #37eef2;text-align: left;">下个实验</span>
  16. </div>
  17. <div style="padding-top: 50px;padding-left: 60px;">
  18. <span style="font-size: 14px;color: #37eef2;text-align: left;">关闭页面</span>
  19. </div>
  20. </div>
  21. <div style="width: 100%;height:250px;float: left;">
  22. <div style="padding-top: 50px;padding-left: 5px;">
  23. <span style="font-size: 14px;color: #9da2ab;text-align: left;">实验名称:
  24. <span style="color: #37eef2;">
  25. 智能合约编辑器2.0
  26. </span>
  27. </span>
  28. </div>
  29. <div style="padding-top: 50px;padding-left: 5px;">
  30. <span style="font-size: 14px;color: #9da2ab;text-align: left;">实验时间:
  31. <span style="color: #37eef2;">
  32. 1小时
  33. </span>
  34. </span>
  35. </div>
  36. <div style="padding-top: 50px;padding-left: 5px;">
  37. <span style="font-size: 14px;color: #9da2ab;text-align: left;">倒计时:
  38. <span style="color: #37eef2;">
  39. 50分32秒
  40. </span>
  41. </span>
  42. </div>
  43. </div>
  44. <div style="width: 100%;height:421px;float: left;">
  45. <div style="padding-top: 50px;padding-left: 5px;">
  46. <span style="font-size: 14px;color: #37eef2;text-align: left;">智能合约编辑器2.0</span>
  47. </div>
  48. <div style="padding-top: 50px;padding-left: 5px;">
  49. <span style="font-size: 14px;color: #9da2ab;text-align: left;">测试实验1</span>
  50. </div>
  51. </div>
  52. </div>
  53. <div style="float:left;width: 90%;height:100%;">
  54. <iframe
  55. ref="myFrame"
  56. src="http://127.0.0.1:3006/#/login"
  57. frameborder="0"
  58. width="100%"
  59. height="980"
  60. ></iframe>
  61. </div>
  62. </div>
  63. </div>
  64. </template>
  65. <script>
  66. export default {
  67. data() {
  68. return {};
  69. },
  70. created() {},
  71. mounted() {
  72. this.iframeInit();
  73. },
  74. computed: {},
  75. methods: {
  76. iframeInit() {
  77. let myFrame = this.$refs["myFrame"];
  78. if (myFrame.attachEvent) {
  79. //兼容浏览器判断
  80. myFrame.attachEvent("onload", function () {
  81. let iframeWin = myFrame.contentWindow;
  82. iframeWin.postMessage(
  83. { router: "/contract", user:localStorage.getItem("userName"), password: localStorage.getItem("passWord")},
  84. "*"
  85. );
  86. //data传递的参数 *写成子页面的域名或者是ip
  87. });
  88. } else {
  89. myFrame.onload = function () {
  90. let iframeWin = myFrame.contentWindow;
  91. iframeWin.postMessage(
  92. { router: "/contract", user: localStorage.getItem("userName"),password: localStorage.getItem("passWord")},
  93. "*"
  94. );
  95. };
  96. }
  97. },
  98. },
  99. };
  100. </script>
  101. <style>
  102. .main {
  103. width: 100%;
  104. min-width: 1200px;
  105. }
  106. .el-message__content {
  107. display: inline-block;
  108. }
  109. .el-message__closeBtn {
  110. display: inline-block !important;
  111. vertical-align: middle !important;
  112. line-height: 0 !important;
  113. }
  114. .home-center {
  115. margin-right: 20px;
  116. }
  117. </style>

5.3 linux环境一键部署

1.下载安装包

  1. wget https://osp-1257653870.cos.ap-guangzhou.myqcloud.com/WeBASE/releases/download/v1.5.1sx/sx-deploy.zip
  1. 解压包
  1. unzip sx-deploy.zip
  2. cd webase-front

3.修改common.properties文件

  1. sx.web.version = v1.5.1sx
  2. webase.web.version=v1.5.1sx
  3. webase.mgr.version=v1.5.1sx
  4. webase.sign.version=v1.5.1
  5. webase.front.version=v1.5.1
  6. # 节点管理子系统mysql数据库配置
  7. mysql.ip=127.0.0.1
  8. mysql.port=3306
  9. mysql.user=dbUsername
  10. mysql.password=dbPassword
  11. mysql.database=webasenodemanager
  12. # 签名服务子系统mysql数据库配置
  13. sign.mysql.ip=localhost
  14. sign.mysql.port=3306
  15. sign.mysql.user=dbUsername
  16. sign.mysql.password=dbPassword
  17. sign.mysql.database=webasesign
  18. # 节点前置子系统h2数据库名和所属机构
  19. front.h2.name=webasefront
  20. front.org=fisco
  21. # sxWEB管理平台服务端口
  22. sxweb.port=5110
  23. # WeBASE管理平台服务端口
  24. web.port=5000
  25. # 节点管理子系统服务端口
  26. mgr.port=5001
  27. # 节点前置子系统端口
  28. front.port=5002
  29. # 签名服务子系统端口
  30. sign.port=5004
  31. # 节点监听Ip
  32. node.listenIp=127.0.0.1
  33. # 节点p2p端口
  34. node.p2pPort=30300
  35. # 节点链上链下端口
  36. node.channelPort=20200
  37. # 节点rpc端口
  38. node.rpcPort=8545
  39. # 加密类型 (0: ECDSA算法, 1: 国密算法)
  40. encrypt.type=0
  41. # SSL连接加密类型 (0: ECDSA SSL, 1: 国密SSL)
  42. # 只有国密链才能使用国密SSL
  43. encrypt.sslType=0
  44. # 是否使用已有的链(yes/no)
  45. if.exist.fisco=no
  46. # 使用已有链时需配置
  47. # 已有链的路径,start_all.sh脚本所在路径
  48. # 路径下要存在sdk目录(sdk目录中包含了SSL所需的证书,即ca.crt、sdk.crt、sdk.key和gm目录(包含国密SSL证书,gmca.crt、gmsdk.crt、gmsdk.key、gmensdk.crt和gmensdk.key)
  49. fisco.dir=/data/app/nodes/127.0.0.1
  50. # 前置所连接节点的绝对路径
  51. # 节点路径下要存在conf文件夹,conf里存放节点证书(ca.crt、node.crt和node.key)
  52. node.dir=/data/app/nodes/127.0.0.1/node0
  53. # 搭建新链时需配置
  54. # FISCO-BCOS版本
  55. fisco.version=2.7.2
  56. # 搭建节点个数(默认两个)
  57. node.counts=nodeCounts

4.部署并启动所有服务

  1. python3 deploy.py installAll

5.部署完成后可以看到deploy has completed的日志:

  1. ============== Starting startSxWeb ==============
  2. ======= sx-web start success! =======
  3. ============================================================
  4. ============== deploy has completed ==============
  5. ============================================================
  6. ============== webase-web version v1.5.1sx ========
  7. ============== webase-web version v1.5.1sx ========
  8. ============== webase-node-mgr version v1.5.1sx ========
  9. ============== webase-sign version v1.5.1 ========
  10. ============== sx-web version v1.5.1sx ========
  11. ============================================================

6 启动和停止所有服务

  1. python3 deploy.py startAll
  2. python3 deploy.py stopAll

7 访问

http://127.0.0.1:5110/sx/#/ 用户名密码需要登录节点管理子系统添加

8 本方案贡献者

贡献者名称github账号
leeduckgo(李骜华https://github.com/leeduckgo
ErQi(齐涛)https://github.com/ErQi
孙丽英https://github.com/sunliying2020