很多时候都很难琢磨客户在想什么, 也许是自己业务经验不足, 也许是客户要显示出他在软件方面也非常的专业. 记得以前听过一个故事, 说一个富人想娶个媳妇, 然后他比较钟意的有三个女人, 然后就想从三个女人中选一个, 他分别给了三个女人各一千块钱, 并对她们说,"我这里有一个房间, 请你们用自己的一千块钱尽可能的将房间填满". 第一个女人, 将 1000 块钱都买了棉花, 但是这些棉花只填满了整个房间的三分之一; 第二个女人, 将 1000 块钱都买了气球, 但是这些气球也只填满了整个房间的三分之二; 第三个女人, 花了 1 块钱买了一支蜡烛, 让蜡烛的光照亮了整个房间. 然后...... 这个富人愉快的娶了其中胸部最大的那个女人. 这个故事告诉我们, 有时你根本不知道客户到底要的是什么!
解决安全登录的问题
去给客户演示系统, 演示完刚开发完的系统以后客户就将我们的系统批的遍体鳞伤, 这时才知道自己的系统比想象中的更不堪. 在如此不堪的系统面前, 客户又提出了一个需求, 要限制用户的登录机器. 补充一下, 演示的系统是一个 ERP 系统, 是 BS 结构的, 用 Java 写的. 客户要求, 要限制能够登录系统的电脑, 需要绑定 MAC 地址. 因为系统里的数据比较重要, 不能让员工回家登录系统, 因此必须要进行限制.
解决思路
这样的问题, 能想到的解决思路只有两个:
1, 在 EXE 文件中嵌入一个浏览器控件, 浏览器中显示 ERP 的页面, EXE 获取 MAC 地址后提交到服务器. 感觉这样先是要处理 EXE 提交的 MAC 地址, 然后还要和页面交互, 想想貌似比较复杂, 就否掉了.
2, 写一个 OCX, 让页面中的 JS 与 OCX 进行交互, OCX 获取到 MAC 地址后, 将 MAC 返回给 JS,JS 通过 DOM 操作写入到对应的表单中, 然后和用户名, 密码一起提交给服务器. 感觉这个好像实现起来还比较简单. 就这个吧!
OCX 中获取 MAC 地址的关键代码
OCX 中可以直接调用 Windows 操作系统的 API 函数, 写起来也比较简单, 代码如下:
- BSTR CGetMacCtrl::GetMacAddress(void)
- {
- AFX_MANAGE_STATE(AfxGetStaticModuleState());
- CString strResult;
- // TODO: 在此添加调度处理程序代码
- ULONG outBufLen = sizeof(IP_ADAPTER_ADDRESSES);
- PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
- if (pAddresses == NULL)
- {
- return NULL;
- }
- // Make an initial call to GetAdaptersAddresses to get the necessary size into the ulOutBufLen variable
- if(GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW)
- {
- free(pAddresses);
- pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
- if (pAddresses == NULL)
- {
- return NULL;
- }
- }
- wchar_t acMAC[32] = { 0 };
- if(GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &outBufLen) == NO_ERROR)
- {
- // If successful, output some information from the data we received
- for(PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses; pCurrAddresses != NULL; pCurrAddresses = pCurrAddresses->Next)
- {
- // 确保 MAC 地址的长度为 00-00-00-00-00-00
- if(pCurrAddresses->PhysicalAddressLength != 6)
- {
- continue;
- }
- wsprintf((LPWSTR)acMAC, _T("%02X-%02X-%02X-%02X-%02X-%02X"),
- int (pCurrAddresses->PhysicalAddress[0]),
- int (pCurrAddresses->PhysicalAddress[1]),
- int (pCurrAddresses->PhysicalAddress[2]),
- int (pCurrAddresses->PhysicalAddress[3]),
- int (pCurrAddresses->PhysicalAddress[4]),
- int (pCurrAddresses->PhysicalAddress[5]));
- break;
- }
- }
- free(pAddresses);
- strResult = acMAC;
- return strResult.AllocSysString();
- }
代码差不多就这样吧, 我用的 VS2012 写的 ActiveX, 编译生成 OCX.
在 web 中进行测试
在 Web 中测试也比较简单, 通过 clsid 引入 OCX 文件, 然后 JS 调用 OCX 文件中的函数, 函数返回 MAC 地址给 JS,JS 进行 DOM 操作, 代码如下:
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="utf8">
- <title > 获取 Mac 地址 Demo</title>
- </head>
- <body>
- <object id="getmac" classid="clsid:52931A6A-93B4-4750-8FE6-B666E90B1D54"
- codebase="'getmac.ocx'" style="display:none"></object>
- <h1>MAC:</h1>
- <span id="mac"></span>
- <input type="text" id="macAddress" name="macAddress" value="" />
- </body>
- <script>
- var mac = getmac.GetMacAddress();
- document.getElementById("mac").innerHTML = mac;
- document.getElementById("macAddress").value = mac;
- document.getElementById("macAddress").style.display = '';
- </script>
- </html>
通过 object 标签引入了 OCX 文件, 定义了 id 为 getmac, 然后通过 getmac 来调用 OCX 中的函数 GetMacAddress() 获取 MAC 地址.
经过简单的测试还是可以的, 然后我整合进入了 JeeSite 系统中 (我其他文章说过, 我们的项目是在 JeeSite 上做二次开发), 测试以后发现 ERP 的页面对 IE 浏览器支持不好. 因为 OCX 只能在 IE 浏览器中使用, 结果这个方案就放弃了. 后来, 找到一个开源的 Chrome 的插件, 也完成 MAC 地址的获取, 该 Chrome 插件分为两部分, 一部分是 Chrome 的插件, 另外一个是 EXE 文件, 该 EXE 文件也是与插件进行通信的, 由于该插件不是我写的, 我就不往这里放了. 总之, 最好还是把客户端这个需求解决了. OCX 的方法就留在这里吧! 也许, 我以后会用到也说不定呢.
来源: https://www.cnblogs.com/tosser/p/9022187.html