杨枝飘泊,桃根娇小,独自个思量。——项鸿祚《太常引·客中闻歌》 楠少博客 阅读文章 Golang 网页跳转保护 楠少 2019-08-01 6666666 8888888 Golang beego 分享 源码 跳转保护 摘要 在QQ邮箱中,访问一些外站链接回弹出跳转提示,以提示用户危险性的存在。 在站点重构时,本地测试GO跳转保护已经实现,都是部署到服务器上时,问题重重,其主要原因时由于`Beego`的跳转函数导致的。 **目录 (Table of Contents)** [TOC] ### 效果截图 ![网页跳转保护截图](https://ae01.alicdn.com/kf/H8f5cdb81edb040508b696d5dc10a5017U.png "网页跳转保护截图") ### qq邮箱跳转保护 在QQ邮箱中,访问一些外站链接回弹出跳转提示,以提示用户危险性的存在。 如图 ![qq邮箱跳转保护](https://ae01.alicdn.com/kf/Hdaef98092b5d4f9f952fe21743b669852.png "qq邮箱跳转保护") 在研究怎么实现的过程中,发现邮件中的链接并没有加上前缀,也就是qq邮箱处理跳转的地址,链接依旧是原始链接,那是怎么实现跳转的呢? 后经查阅,我猜想实现发式:为每个待处理的a标签,添加`点击事件监听`。 由于 `onclick` 的优先级大于 `href`,并且 `onclick` 处理后可以拦截 `href` 的链接跳转。 ### 网站GO跳转保护经历 #### 初期 在站点重构时,本地测试GO跳转保护已经实现,都是部署到服务器上时,问题重重,其主要原因时由于`Beego`的跳转函数导致的。 前期处理的过程中,由于还有其他功能未完善,所以就先将此功能闲置了下来。 #### 错误原因及解决方案 经查:beego 中 `Redirect` 跳转到非当前主机的链接时,回替换主机为当前主机,从而出现问题。 解决:利用 `WriteString` 写 `JavaScript` 在前端实现跳转。 但是速度没有302跳转的速度快。 #### 后期解决 现在问题已经解决,效果地址:`https://blog.nanshaobit.top/go/[链接的BASE64编码]` ##### 站外测试: 跳转百度:[点击试试](http://baidu.com "点击试试") ##### 站内测试 跳转域名下网站:密码本:[点击试试](https://pwd.nanshaobit.top "点击试试") ### 思路分析 #### 前端引导进入 前端在需要跳转保护的链接上添加进入保护程序的引导 有两种方案: 1.设置js点击事件监听 2.直接在a标签的href上处理 #### 后台处理 获取到按自定协议传递过来的url地址原始链接 如果按自定协议解析失败 跳转404 ![404截图](https://ae01.alicdn.com/kf/H0cd4d1e4a813442f80c9031f182eadf3P.png "404截图") 解析后 需要处理特殊情况 如:为填写http|https协议 或者为其他协议:mailto|ftp 、、、 然后判断是否为本站链接,如果是,直接放行,否则进入跳转保护页面 提示用户 ### 源码分享 #### 前端 ```javascript // 循环遍历所有需要添加跳转保护DOM的a标签 for (i = 0; i < $(".newsview a").length; i++) { e = $(".newsview a")[i]; // if 中是排除跳转保护,这里排除的是文档目录。 // 如果不需要排除的话,将if条件语句删除,代码快内的代码直接拿出来 if (e.className.indexOf("toc") == -1) { e.href = "/go/" + window.btoa(e.href); e.target = "_blank"; } } ``` #### 后台 路由: ```go beego.Router("/go/*", &controllers.BaseController{},"get:Url") ``` 方法: ```go // 函数功能 :判断是否为自己的 // 传入参数 :url(string):当前保护访问的域名,myDomain(string)本站域名 // 返回类型 :bool func isMyDomain(url string, myDomain string) bool { // 将所得URL 转小写 url = strings.ToLower(url) // 去掉 端口号、http|https 协议 r, _ := regexp.Compile("http[s]*://") u := r.ReplaceAllStringFunc(url, func(in string) string {return ""}) r, _ = regexp.Compile(":[0-9]*") u = r.ReplaceAllStringFunc(u, func(in string) string {return ""}) // 提取出域名 u = strings.Split(u,"/")[0] // 判断长度,如果域名长度小于配置域名长度 返回 false if len(u) < len(myDomain){ return false } // 截取当前域名的后半部分(即 到二级域名)与配置域名对比 if u[len(u)-len(myDomain):] == myDomain{ return true } // 默认返回 false return false } func (c *BaseController) Url() { url := strings.Split(c.Ctx.Request.RequestURI,"/go/")[1] // 获取base64编码后的字符串 url1 ,_ := base64.StdEncoding.DecodeString(url) // 解码字符串成网址赋值给url url = string(url1) urlList := strings.Split(url,".") // 地址中如果没有 `.` 直接报404 if len(urlList) == 1{ c.Abort("404") } // 处理未填写 http|https 协议的情况 (排除其他协议) if len(strings.Split(urlList[0], ":")) == 1 && len(strings.Split(urlList[0],"//")) == 1{ url = "http://" + url } // 判断是否为自己的域名 配置域名从 config 文件中读取 if isMyDomain(url,beego.AppConfig.String("mydomain")){ // 是的情况 通过js 实现跳转 c.Ctx.WriteString("<script>window.location.href='"+url+"'</script>") return } // 否的情况 显示跳转提示页面 c.Data["url"] = url c.TplName = "go.html" } ``` 注意点: + 配置域名的时候填写 小写 到二级域名 即可 【不需要带协议,不需要带端口号 小写】 + 本站填写的是 :nanshaobit.top 而不是 blog.nanshaobit.top ## END 上一篇:搜索已死,谁来烧纸? 下一篇:字节跳动,正在动摇互联网的根基! 文章评论 跳转保护功能可以有效避免用户点击到恶意网站上当受骗。 #1 2020-01-04 18:00:25 回复 [ 聊聊技术 聊聊自己 ] 在巴甫洛夫条件反射 试验中:给定一条狗,每次摇铃后喂食,足够次数后,狗则听到铃声将会习惯性的分泌唾液,由此引发对铃声的依恋。延伸到实际,给定一个喜欢的妹子,每次见面赠与巴甫洛夫式 的礼品或者零食,由此引发妹子的依恋。引入薛定谔的猫 理论,在未表白前,妹子与自己一直处于一种“概率云”的状态,一旦表白则“概率云”将消失成为实际。在 巴甫洛夫式 后且未表白前,自己与妹子的关系为“既是恋人又不是恋人”的矛盾体。返回巴甫洛夫式 试验中,在妹纸形成足够的依恋过后,则可以打破薛定谔 “概率云”的状态。这个谜一样的自己,这一刻 薛定谔 附体,带着量子论般深沉的哀愁,让她从此不能自拔! 自此创作 巴甫洛夫薛定谔把妹法,深藏功与名。