如何删除用户头像文件?

各位好,

我的 网站 托管在中国。众所周知,所有中国网站都需要向政府申请备案许可证,因此所有中国网站都处于监管之下。

最近有人向我的 CDN 服务商七牛云(也是一家中国公司)举报,称我网站上的某些图片是非法的。七牛云通知我,必须删除这些图片并“刷新 URL 缓存”,否则他们将依法暂停我的账户。但我发现这些图片是用户头像,我不知道该如何删除。

根据 How to Delete Uploaded Files? - #3 by codinghorrorHow to Delete Uploaded Files? - #25 by Falco 的说明,没有引用的上传文件将在 48 小时内自动删除。我已将这些用户头像替换为默认的字母头像,但 72 小时后旧的头像似乎仍未消失,可能是因为用户头像不被视为“上传文件”?

请问有什么方法可以彻底删除服务器上的用户头像文件吗?

提前感谢,
Yinglu

我认为它仍然按这种方式工作。

从要删除的文件 URL 中获取文件名。

cd /var/discourse/shared/uploads
find . -name =FILENAME= | xargs exec rm

然后,您需要执行相应操作以将其从 CDN 中清除。

感谢你的帮助,我试过了但没成功 :frowning:

文件链接是 https://iosre.com/user_avatar/iosre.com/lincwee/135/5414_2.png,所以我猜文件名应该是 5414_2.png,对吗?

另外,/uploads 目录位于 /shared/standalone 下,而不是 /shared
而且 /uploads 下并没有这个文件,从 shell 输出可以看出:

root@iosre:/var/discourse/shared# ls
standalone
root@iosre:/var/discourse/shared# cd standalone/
root@iosre:/var/discourse/shared/standalone# ls
backups  postgres_backup  postgres_run  state  uploads
log      postgres_data    redis_data    tmp
root@iosre:/var/discourse/shared/standalone# find . -name 5414_2.png
root@iosre:/var/discourse/shared/standalone# cd uploads/
root@iosre:/var/discourse/shared/standalone/uploads# find . -name 5414_2.png
root@iosre:/var/discourse/shared/standalone/uploads#

还有其他建议吗?

抱歉,头像的运作方式不同。我需要查看代码才能知道该从哪里入手。如果这是紧急情况且您有预算,请直接联系我。否则我可能没有空闲时间进行调查。也许其他人知道。

抱歉,这是一个个人网站,我目前没有任何预算。无论如何,感谢您的回复!

为防止用户上传新的头像,您可以禁用“允许上传头像”选项,并启用“可选择头像”站点设置,同时提供大量选项。

我认为您可能需要_上传一个替换用的占位符_,才能实现自动删除——即使用户头像已不再使用,用户记录仍会保留该已上传的头像图片。


上传的文件是根据图片内容的 SHA1 哈希值命名的——这或许能帮助您找到对应的源文件?

类似如下:

a=UserAvatar.where(user_id: 1234)
u=Upload.find(a.custom_upload_id)
upload_url=u.url

然后:

cd /var/discourse/shared/standalone
rm 上面的上传链接

我有超过 7000 名注册用户,其中只有不到 5 名用户在不知情的情况下使用了非法头像,因此我不想将其变成“非 0 即 1”的问题;我希望逐案解决,而不是禁止所有用户使用自定义头像。

我该怎么做?我完全不知道。

例如这张图片:https://iosre.com/user_avatar/iosre.com/lincwee/135/5414_2.png

snakeninny@bogon ~ % shasum /Users/snakeninny/Desktop/5414_2.png.jpeg 
c8d561c5484a1f197abd32995411caaa25e53bd6  /Users/snakeninny/Desktop/5414_2.png.jpeg
root@iosre:~# cd /var/discourse/shared/standalone
root@iosre:/var/discourse/shared/standalone# find ./ -name *c8d561c5484a1f197abd32995411caaa25e53bd6*
root@iosre:/var/discourse/shared/standalone# 

没有结果。你指的是这个吗?有什么建议吗?

这是一段代码吗?在哪里以及如何执行它?我过去是 iOS 开发者,不熟悉前端编程。

这是用于 Rails 控制台的。你可以通过以下命令进入:

cd /var/discourse 
./launcher enter app 
rails c

你可以使用 exit 退出。在容器内,请切换到 /shared 目录,而不是使用上面的完整路径。

用户 lincweehttps://iosre.com/user_avatar/iosre.com/lincwee/135/5414_2.png 的头像
UserAvatar.where(user_id: 'lincwee') 返回空数组。有什么建议吗?

root@iosre:~# cd /var/discourse/shared/
root@iosre:/var/discourse/shared# /var/discourse/launcher enter app 
WARNING: Docker version 17.05.0-ce deprecated, recommend upgrade to 17.06.2 or newer.
root@iosre-app:/var/www/discourse# rails c
[1] pry(main)> a=UserAvatar.where(user_id: 1234)
=> []
[2] pry(main)> a=UserAvatar.where(user_id: lincwee)
NameError: undefined local variable or method `lincwee' for main:Object
from (pry):2:in `__pry__'
[3] pry(main)> a=UserAvatar.where(user_id: 'lincwee')
=> []
[4] pry(main)> 

你需要的是 ID,而不是用户名。

u = User.find_by(username: "lincwee")

然后你可以查看 ID,或通过 u.id 访问它。

谢谢,这在一定程度上起作用了。我在终端中运行了以下命令:

cd /var/discourse/shared/
/var/discourse/launcher enter app
rails c

然后执行了以下代码:

uid = User.find_by(username: "user_name").id
user_avatars = UserAvatar.where(user_id: uid)
user_avatar = user_avatars[0]
upload_url = Upload.find(user_avatar.custom_upload_id).url

以列出所有头像 URL 并从服务器上删除它们。

但我猜我还需要进一步刷新系统或缓存?我该如何操作?

我又收到了一封来自 CDN 提供商的邮件,他们已冻结了我的 CDN 账户。因此,我需要更新此帖子以寻求进一步的帮助。

新邮件指出以下链接涉及非法内容:

https://cdn.iosre.com/user_avatar/iosre.com/baal998/135/2210_2.png
https://cdn.iosre.com/user_avatar/iosre.com/baal998/64/2210_2.png
https://cdn.iosre.com/user_avatar/iosre.com/baal998/75/2210_2.png
https://cdn.iosre.com/user_avatar/iosre.com/baal998/75/2210_2.png
https://cdn.iosre.com/user_avatar/iosre.com/baal998/75/2210_2.png
https://cdn.iosre.com/user_avatar/iosre.com/lincwee/135/5414_2.png
https://cdn.iosre.com/user_avatar/iosre.com/baal998/75/2210_2.png
https://cdn.iosre.com/user_avatar/iosre.com/lincwee/75/5414_2.png
https://cdn.iosre.com/user_avatar/iosre.com/baal998/96/2210_2.png
https://cdn.iosre.com/user_avatar/iosre.com/lincwee/90/5414_2.png

如您所见,这些是两个用户的头像,内容涉及一位已故中国领导人的恶搞图片。同样,CDN 提供商要求我删除服务器上的这些文件并刷新 CDN。

从链接中可以看出,相关用户是"baal998"和"lincwee"。根据我上一帖中的代码片段,"lincwee"上传的头像 URL 为 /uploads/default/original/2X/5/55512211b1c8969c8038b79840464952cd3eb089.jpeg,而"baal998"的则为 /uploads/default/original/2X/c/cb2188eaeecc3a648f021fa00da4734bd60ca183.jpg。随后我运行了 find /var/discourse/shared/ -name *55512211b1c8969c8038b79840464952cd3eb089* 并删除了所有找到的文件,这对"lincwee"生效了。但"baal998"的情况就不幸了,即使服务器上已不存在任何名为 *cb2188eaeecc3a648f021fa00da4734bd60ca183* 的文件,我仍然可以访问 https://iosre.com/user_avatar/iosre.com/baal998/135/2210_2.png。

那么,https://iosre.com/user_avatar/iosre.com/baal998/135/2210_2.png 到底存储在我服务器的哪个位置呢?:sob:

嗯,这确实是个棘手的情况。也许 @falco 或者最近参与过头像开发的其他人可以给你一些建议?

或者更简单地说:Discourse 是如何解析对 https://iosre.com/user_avatar/iosre.com/baal998/135/2210_2.png 的访问的?如果熟悉源代码的人能告诉我相关的源文件、类或函数,那将非常有帮助。谢谢!

我想应该是在 Uploads 模型里查看。

另外,先从你的服务器拉取数据,而不是 CDN。你需要确保在正确的地方解决问题。一旦确认服务器没有发送图片,再着手处理 CDN 的问题。

既然 https://cdn.iosre.com/user_avatar/iosre.com/baal998/135/2210_2.png 来自 CDN,
那么 https://iosre.com/user_avatar/iosre.com/baal998/135/2210_2.png 应该来自我的服务器,对吗?

是的,你看到它正由你的服务器发送。因此,需要修复的正是这个链接。在你停止发送这些图片后,可以清除 CDN。