一文搞定防盗链设计

大家好,我是蓝胖子,在涉及到图片或者视频链接时,通常都会提到防盗链,这一节我将会从防盗链的含义到落地,向大家展示如何设计资源的防盗链。

防盗链的含义与作用

防盗链,顾名思义,是为了防止资源被他人窃取而设计的。

通常我们将图片或视频链接存储到obs对象存储上,前端通过服务端返回的图片或视频链接访问obs上对应的资源,那如果这个链接被第三方网站获取到,便能在其网站上直接访问我们的视频或者图片资源。

防盗链的出现就是为了杜绝第三方网站能直接访问我们的视频或图片资源。让返回的资源链接只能被我们指定的网站进行访问

防盗链方案设计

接着,我以华为云的obs系统 为例, 讲几个关于防盗链的设计方案,供大家参考,

refer指定黑白名单

浏览器在加载静态资源时,会在请求头中加上Refer字段,其值为浏览器当前的网址,目的是为了告诉服务器,用户在访问资源之前的位置。

如果第三方网站获盗取到了我们的视频资源,那么在其访问时,Refer就是第三方网站的网址,我们可以在obs上配置reder黑白名单,指定资源让某些网站不允许访问或者对某些网站允许访问。

Pasted image 20240401163901.png

更加灵活的鉴权方式-远程鉴权

除此以外,还有种更加灵活的鉴权方式,通过自定义的代码来判断该访问链接是否允许被访问。在使用obs系统时,为了减少带宽成本,我们将会在obs前面,部署cdn节点,让用户访问的资源能够被缓存到离他比较近的cdn节点上。

通常cdn节点上可以配置对应的访问,例如华为云可以配置远程鉴权的地址,指向自己的服务器鉴权接口,在接口中定义对资源的访问权限,像cloudflare则是可以创建worker,在worker中定义链接的访问权限。

Pasted image 20240401164545.png

鉴权逻辑应该如何写,这里我提供一个比较通用的逻辑,给大家参考下。

在服务端返回给客户端资源在obs上的访问链接时,可以加上该链接的创建时间,在鉴权逻辑里申明一个链接的有效期,根据链接的产生时间和有效期 允许该链接在有效期内允许访问,比如返回给客户端的链接是

https://xxx?ctime=1711962048

ctime 则是链接的创建时间,但是仅仅这样是不够的,第三方网站可以获取到链接后修改ctime字段来修改链接的创建时间,所以我们还需要一个消息认证的机制,保证链接是服务器返回的且没有经过篡改,这里可以用消息认证算法实现。

拿消息认证算法hmac举例,服务器端定义一个只有自己知道的密钥,用该密钥对资源地址进行md5的摘要计算,如下是golang中的hamc的使用逻辑,

key := "hamcsecrete"
    data := "https://xxx?ctime=1711962048"
    hmac := hmac.New(md5.New, []byte(key))
    hmac.Write([]byte(data))
    fmt.Println(hex.EncodeToString(hmac.Sum([]byte(""))))

得到的消息认证码,加入到资源链接的参数中,如下,

https://xxx?ctime=1711962048&token=679f5d6f7d344dba1e33938ae1d41ab4

这样,鉴权服务器在得到资源链接时,就会将资源地址通过同样的消息认证算法和密钥计算token值,如果计算出的token值和资源链接中的token值一致,则继续查看链接是否在有效期范围内,在则允许访问,否则不允许访问。因为消息认证的密钥只有服务器知道,即使第三方网站获取到了链接,也无法得出正确的token值。

最后,在使用此逻辑的时候,要注意cdn服务器回源的条件,通常cdn是根据url路径查看是否需要回源,如果url地址不同,则会去访问源站服务器,我们当然不希望因为链接ctime的不同就再次去请求源站服务器,所以,在cdn节点处,需要配置,判断回源时需要忽略ctime和token的参数。

责任链设计模式是一种行为型设计模式,用于将请求的发送者和接收者解耦,使多个对象都有机会处理该请求。该模式将这些对象串成链,并沿着这条链传递请求,直到有一个对象能够处理它为止。 责任链模式的核心是定义一个处理请求的抽象类或接口,然后让多个具体的处理者对象继承或实现这个类/接口。每个具体的处理者对象都包含一个对下一个处理者对象的引用,形成一个链式结构。 当一个请求进入责任链时,责任链中的每个处理者都有机会处理该请求。如果可以处理请求,则进行处理;如果不能处理,则将请求传递给下一个处理者,直到有一个处理者能够处理它。 责任链模式的关键点是要找到合适的处理者顺序和条件。通常情况下,责任链模式适用于以下情况: 1. 有多个对象可以处理同一类型的请求,但具体由哪个对象来处理由运行时决定。 2. 不明确请求的接收者,希望请求在一个对象链中流动,直到被处理。 3. 需要动态地指定可以处理请求的对象集合。 使用责任链模式可以实现请求发送者和接收者的解耦,增加代码的灵活性和可扩展性。但同时也需要注意责任链的长度和效率问题,避免责任链过长或造成性能问题。 总结一下,责任链设计模式是一种将请求发送者和接收者解耦的设计模式,通过将多个处理者对象串成链,沿着这条链传递请求,直到有一个处理者能够处理它。这样可以增加代码的灵活性和可扩展性,适用于有多个对象可以处理同一类型请求的情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝胖子的编程梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值