用go gui 框架wails 包装现有的web项目

用go gui 框架wails 包装现有的web项目

上头要求要对已有项目的接口数据进行加密,非对称加密,主要的难点在于,怎么在前端项目中把请求数据进行加密,可能是见识太少了,没想到非常安全的方式,所以想到通过包装web项目的方式实现。

方案确定

技术方案有两种选择

  • electron ①
  • wails ②

以上两种方式都可以把web项目进行包装,

①在实践的时候需要对现有的web项目依赖包进行重新适配、改造,制作完成的安装包大概在60-70M左右,

②只需要简单的处理下请求的部分,或者不处理就可以直接打包进去,制作完成的安装包,只有20M不到

第一版实践

wails项目的项目结构如下

css 复制代码
wailsClient
├─api
├─build
├─frontend
│ ├─dist
│ └─....
├─httpProxy
├─main.go
└─wails.json

只需要把前端打包的文件放到dist 的位置,然后执行

arduino 复制代码
wails build -s  // -s 表示不进行前端资源编译

直接把项目放进去打包,启动起来,发现无法所有的接口都无法请求,F12打开看看,发现项目的根路径是,

arduino 复制代码
http://wails.location.com

如图:

如此肯定请求不到接口的。

wails文档中,资源服务器(AssetServer)配置可以对前端的请求进行处理,如下配置,需要实现一个自定义的http.Handler

yaml 复制代码
AssetServer: &assetserver.Options{
    Assets:  assets,
    Handler: 自定义http.Handler,
},

文档参考:wails.io/zh-Hans/doc... 动态资产

自定义http.Handler,这里面接收到前端的请求以后,转发到真实的API服务器

go 复制代码
type FileLoader struct {
	http.Handler
}

func NewFileLoader() *FileLoader {
	return &FileLoader{}
}

func (h *FileLoader) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    // 框架带过来的 content-length 是0 ,ReverseProxy 代理的时候就不转发body ,设置成1
	r.ContentLength = 1 
	u, err := url.Parse("http://xxx.xxx.com") // 这里是真实的API接口地址
	if err != nil {
		log.Println(err.Error())
		return
	}
	proxy := httputil.ReverseProxy{
		Director: func(req *http.Request) {
			req.URL.Host = u.Host
			req.URL.Scheme = u.Scheme
			req.Host = u.Host
			body, _ := io.ReadAll(req.Body)
			req.ContentLength = int64(len(body))
			buff := bytes.NewBuffer(body)
			req.Body = io.NopCloser(buff)
		},

		ErrorLog: log.New(os.Stdout, "ReverseProxy:", log.LstdFlags|log.Lshortfile),
	}

	proxy.ServeHTTP(w, r)
}

如此,前端的所有请求就不会有问题了,接下来就是在Handler这里面处理加密的事情,省略掉,主要说下包装的事情。

如此啊基本的需求是可以实现了,但是请求发现数据接口多的情况下,有好多请求会被挂起,导致前端响应很慢

查了下原因是浏览器限制的并行请求数的问题,单次只能并行10个请求,刚进来请求的比较多,就太多的挂起。

第二版实现

基本的功能实现了,但是请求是有点慢的,想把所有的POST请求不走浏览器,做一个类似mock的东西,把所有Axios请求拦截,然后调用go方法做请求,然后把响应数据返回。

如此,请求实际上并没有通过浏览器发起,而是通过 模拟的Mock 拦截了请求,通过 Js 与 Go 程序交互,调用 Go 方法,做数据请求。

这种方式需要修改下axios 请求的地方,修改如下

js 复制代码
const service = axios.create({
	baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
	timeout: 1000 * 30, // 请求超时时间设置
  adapter:config => {

    // 模拟服务,返回mock数据
    let postDate={
      baseURL:config.baseURL,
      data:config.data,
      headers:config.headers,
      method:config.method,
      timeout:config.timeout,
      url:config.url,
    }
    console.log(postDate)
    return  DoRequest(postDate)
  }
})

配置一个 adapter ,拦截请求,DoRequest 是Go程序暴露出来的一个方法(自己写的),如下,具体的实现可参考wails文档编写。

go 复制代码
func (a *App) DoRequest(reqInfo AxiosDate) (resposne AxiosReponse) {

	baseUrl := "http://xxx.xxx.com"
	bs, err := Post(baseUrl+reqInfo.Url, reqInfo.Data, nil, reqInfo.Headers)

	if err != nil {
		resposne.Status = 400
		return
	}
	resposne.Status = 200
	resposne.StatusText = "ok"
	resposne.Data = string(bs)

	log.Print(reqInfo)
	log.Print(resposne)
	return resposne
}

参考 wails.io/zh-Hans/doc...

如此,所有的接口请求都走了go程序,就绕过了浏览器并发请求数的限制。

下来就是在请求的地方做加解密处理。

总结

如此,把web项目包装起来,请求通过go程序进行加解密,完美实现请求加密的需求。

相关推荐
獨枭4 分钟前
使用阿里云远程访问 Synology Web Station 的指南
前端·阿里云·云计算
zqwang8887 分钟前
Vue3.5正式上线,父传子props用法更丝滑简洁
前端·javascript·vue.js
清灵xmf35 分钟前
为什么 Vue3 封装 Table 组件丢失 expose 方法呢?
开发语言·前端·javascript·封装·eltable
SophieBryant40 分钟前
鸿蒙实现 web 传值
前端·华为·harmonyos
w2830651 小时前
前端web
前端
理想不理想v2 小时前
高级前端开发工程师--掌握的技术
java·前端·javascript·typescript
贺今宵2 小时前
vue使用vite-plugin-svg-icons插件组件化svg图片
前端·javascript·vue.js
linzhisong2 小时前
LayUI组件国际化多国语言版本脚本-下篇根据语种替换
前端·javascript·python·layui
LAY家的奶栗子是德云女孩2 小时前
HTML5+CSS前端开发[保姆级教学]+基本文本控制标签介绍
前端·css·html·学习方法
遗憾何来3 小时前
第9章综合案例————众成远程教育
前端·javascript·css