可能很多朋友会觉得,前端其实是没有必要进行静态代码分析的,殊不知,往往一些关键点会出现在前端代码中,比如前后端交换加密的算法,以及一些接口的使用方法。
分析的源项目地址:
ps:是一个利用知识图谱构建知识库的开源项目,领域知识的构建。

针对上一篇中的开源项目,这一篇我们开始分析其前端部分的代码。
在这里插入图片描述

前端部分的代码在studio/webui下,打开目录,我们可以看到这样一个结构:
在这里插入图片描述

抛开Dockerfile和webui.go这样的构建打包文件不谈,这就是一个前端项目的标准结构。

构建前端调式环境

首先,需要了解的一个点是,这样项目的API结构究竟是如何调用的,这类前端工程化的项目一般都会全局配置代码,所以需要找到全局配置的文件。
在这里插入图片描述

这里应该是对不同的url前缀调用不同的接口,这里就要使用到我们之前搭建的远程服务器。

从代码来看,这里区分了以下几种前缀:

prefixtargetdescription
/api/builderhttp://10.4.69.51在注释里面有:http://10.2.174.230:6475
/api/studiohttp://10.4.69.51http://10.2.174.230:6800
/api/enginehttp://10.4.69.51http://10.2.174.230:6474

然后我们再翻看以下开源版本打开的docker情况:
在这里插入图片描述

发现刚好有注释中的几个端口,那么我们直接将该项目启动起来,target配置成我们在远端的地址。
同时上面的前缀也和我们的文档里面的描述一致
在这里插入图片描述

然后执行

yarn start

启动项目即可。
额,失败了。应该是改版了,还是改成只配置一个相同的。成功。
在这里插入图片描述

在这里插入图片描述

我们现在就构建起了整个前端调试的环境,即:前端使用本地,调用远程服务器端口。

分析前端结构

在这里插入图片描述

首先,assets是资源目录,里面包含了各类静态资源。
components是组件目录,页面即组件,组件是嵌套的。
download是要下载的文件,不过我认为这个部分其实可以放在后端,以接口的形式将下载流传给前端,否则每一次更新文件,都得重新拉取镜像,打包(考虑镜像成本)。
enums是一些枚举值;
hooks是拦截统一处理,以前在写web漏洞扫描器的时候,使用无头浏览器就需要对页面进行hook,注入相关的函数收集信息。
locales,我的理解应该是对后端字段的翻译,因为项目有中文和英文两种模式,而在这两种模式下对于同一个字段的不同描述是不同的,那么这里做的就是这个事儿。
pages,界面业务逻辑大多写在这个位置。
reduxConfig,redux组件的配置,redux我感觉有点像一个大缓存,里面根据组件+某些算法来生成键,进而维护组件的状态和动态属性。
services,统一维护调用的接口;
utils,一些工具类和方法。

获取URL

在进行繁杂的前端调试之前,也可以进行以下步骤,因为有接口文档,
但是大量的开源项目其实是没有接口文档的,那么我们就应该掌握分析接口的能力。

从上面的分析我们可以得到,services目录下的就是统一维护的接口。那么我们需要利用熟悉的语言编写解析程序,对代码进行结构化分析和关键信息提取。我这里就使用JAVA:

public class ReactProjectHandler {

    public static Pattern pathPattern = Pattern.compile("`\\$(?<url>[\\/0-9a-zA-Z_]+)`");


    public static void handleApiTs() {
        String baseBuilder = "/api/builder/v1";
        String baseEngine = "/api/engine/v1";
        String baseStudio = "/api/studio/v1";
        String fileName = "D:\\个人\\anydata\\kweaver\\studio\\webui\\src\\services\\api.ts";
        List<String> a = FileUtils.getListKeyWithOneLine(fileName, false);
        List<String> urls = new ArrayList<>();
        for (String b : a) {
            String c = StringFormatUtils.formatByName(b, new HashMap<String, Object>() {
                {
                    put("baseBuilder", baseBuilder);
                    put("baseEngine", baseEngine);
                    put("baseStudio", baseStudio);
                }
            });
            Matcher matcher = pathPattern.matcher(c);
            if (matcher.find()){
                String url = matcher.group("url");
                urls.add(url);
            }
        }
        Collections.sort(urls);
        for (String url : urls){
            FileUtils.appendFileWithRelativePath("anydata","apis.txt",url+"\n");
        }
    }

    public static void main(String[] args) {
//        String folderName = "";
//        String ignores = ".less,test.js,test.tsx";
//        FolderUtils.Dir dir = FolderUtils.getFolder(folderName, ignores);
        handleAllApis();
    }

}

这个程序将分析api.ts文件,并输出到结果文件中,那么我们收集的api就有如下内容:

/api/builder/v1/onto/ds
/api/builder/v1/onto/gettabbydsn
/api/builder/v1/onto/previewdata
/api/builder/v1/onto/dirlist
/api/builder/v1/onto/auto/autogenschema
/api/builder/v1/onto/getotl
/api/builder/v1/onto/getotlbyname
/api/builder/v1/onto/saveontology
/api/builder/v1/onto/modellist
/api/builder/v1/onto/
/api/builder/v1/graph/getdsbygraphid
/api/builder/v1/graph/
/api/builder/v1/onto/modelspo
/api/builder/v1/onto/getmodelotl
/api/builder/v1/onto/task/build_task
/api/builder/v1/onto/task/gettaskinfo
/api/builder/v1/onto/task/deletetask
/api/builder/v1/onto/task/get_task_files
/api/builder/v1/onto/task/deletealltask
/api/builder/v1/onto/updatename/
/api/builder/v1/onto/updateinfo/
/api/builder/v1/ds/testconnect
/api/builder/v1/ds
/api/builder/v1/ds/ds_copy
/api/builder/v1/ds
/api/builder/v1/graph/ds/
/api/builder/v1/ds/
/api/builder/v1/ds/delbydsids
/api/builder/v1/ds/searchbyname
/api/builder/v1/ds/Auth
/api/engine/v1/analysis
/api/engine/v1/explore/relation
/api/engine/v1/explore/expandv
/api/engine/v1/explore/path
/api/engine/v1/explore/pathDetail
/api/builder/v1/graph/output
/api/builder/v1/graph/input
/api/builder/v1/knw/get_all
/api/builder/v1/knw/get_by_name
/api/builder/v1/knw/network
/api/builder/v1/knw/edit_knw
/api/builder/v1/knw/delete_knw
/api/builder/v1/knw/get_graph_by_knw
/api/builder/v1/graph/info/onto
/api/builder/v1/graph/info/basic
/api/builder/v1/graph/info/count
/api/builder/v1/graph/info/detail
/api/engine/v1/properties
/api/builder/v1/onto/getbykgid
/api/studio/v1/graphdb
/api/studio/v1/graphdb/list
/api/studio/v1/graphdb/add
/api/studio/v1/graphdb/delete
/api/studio/v1/graphdb/update
/api/studio/v1/graphdb/test
/api/studio/v1/graphdb/graph/list
/api/studio/v1/opensearch/list
/api/studio/v1/opensearch
/api/studio/v1/opensearch/add
/api/studio/v1/opensearch/delete
/api/studio/v1/opensearch/update
/api/studio/v1/opensearch/test
/api/builder/v1/task
/api/builder/v1/task
/api/builder/v1/task/stoptask
/api/builder/v1/task
/api/builder/v1/task/get_progress
/api/builder/v1/graph/delbyids
/api/builder/v1/task
/api/builder/v1/timer
/api/builder/v1/timer/info
/api/builder/v1/timer/delete
/api/builder/v1/timer/add
/api/builder/v1/timer/update
/api/builder/v1/timer/switch
/api/builder/v1/graph
/api/builder/v1/graph
/api/builder/v1/graph
/api/builder/v1/graph/getbis
/api/builder/v1/graph/savenocheck
/api/builder/v1/graph/check_kmapinfo
/api/builder/v1/graph/graph_InfoExt/graphid
/api/studio/v1/swaggerDoc
/api/builder/v1/lexicon/getall
/api/builder/v1/lexicon/getbyid
/api/builder/v1/lexicon/create
/api/builder/v1/lexicon/labels
/api/builder/v1/lexicon/export
/api/builder/v1/lexicon/edit
/api/builder/v1/lexicon/delete
/api/builder/v1/lexicon/import_words
/api/builder/v1/lexicon/insert
/api/builder/v1/lexicon/search
/api/builder/v1/lexicon/edit_words
/api/builder/v1/lexicon/delete_words
/api/builder/v1/lexicon/template
/api/builder/v1/lexicon/word_cloud
/api/builder/v1/lexicon/word_cloud_search

我们来观察下代码:
在这里插入图片描述

可以发现这里其实有组装链接的情况,也就是说光分析api.ts,我们查看到的接口只是局部,无法看到所有东西,那么我们还需要考虑对这个目录下的js代码进行解析处理。

好了,吃午饭了。有空了再写。

Logo

GitCode 官方账号,发布 GitCode 官方信息。包括产品更新、官方活动及优秀项目/组织推荐等。官方客服邮箱:kefu@gitcode.com

更多推荐