-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Hello everyone,
For one of my projects I am working on, I want to add a feature to add image posts.Not only that I want users to be able to add images, but I want to enable those images to be visible only to registered users.
The second thing I want to accomplish is even for registered users (who can see these image posts) to not be able to access "View image" or contents of the file. The reason being is, I don't want anyone to be able to download images from my app, because I want to avoid possible legal issues of "distributing content without consent" or some stupid thing like that.
Keep in mind that I have Vue 3 app on client, and .Net 7 Api on backend.
SOLUTION 1: For my original solution, I have implemented the following helper method (which works):
[NonAction] // I don't want this to be called outside my controllers
internal async Task<FileStreamResult> DownloadFile(string filePath)
{
var fileContents = await GetFileStream(filePath);
var fileName = filePath.Split('/').Last();
var mimeTypeFetchResult = new FileExtensionContentTypeProvider().TryGetContentType(filePath, out var contentType);
// Defaults to pdf
if (mimeTypeFetchResult == false)
contentType = MediaTypeNames.Application.Pdf;
return File(fileContents, contentType, fileName);
}
And if I am using my controller I am using it like (this is an example code):
[Authorize]
[HttpGet, Route("GetImageOriginalSolution")]
public async Task<IActionResult> GetImageOriginalSolution()
{
var filePath = Path.Combine("C:\\Files\\UploadedImages\\38c8617a-14a5-4bf5-9f39-1bca4bc0dd4e.jpg");
return await DownloadFile(filePath);
}
I am basically downloading file on my vue client app, and I am reconstructing the Blobs to set an image source. If people try to "View image" it will just be uncohersive string of content characters.
This is working fine, but it is performance killer. Even in my local dev enviroment, the first 5 posts on Dashboard are loaded OK (with slight delay), but every post after makes the system laggy and unusable.
SOLUTION 2: After looking at solutions after the fact, I have found the following documentation about static files on .Net: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-7.0#static-file-authorization-1
I have implemented a recommended solution:
Startup.cs
` var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString();
app.UseStaticFiles(new StaticFileOptions
{
// FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "MyStaticFiles")),
FileProvider = new PhysicalFileProvider(Settings.BaseFolder),
RequestPath = "/StaticFiles",
// This will control how long does browser cache the image user has opened
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Append(
"Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}");
}
});`
And if in my controller I am using it like so (this is example code):
[Authorize]
[HttpGet, Route("GetImageMicrosoftDocsSolution")]
public async Task<IActionResult> GetImageMicrosoftDocsSolution()
{
var filePath = Path.Combine("C:\\Files\\UploadedImages\\38c8617a-14a5-4bf5-9f39-1bca4bc0dd4e.jpg");
return PhysicalFile(filePath, "image/jpeg");
}
Both of these solutions work with Authorization, and unauthorized people cannot access them. The second solution even adds automatic caching. It also keeps people from downloading them, and honestly I dgaf about screenshots, as I have done my due diligence to prohibit people from downloading stuff.
My questions are basically:
- What is the better option of the two?
- Should I just be serving static files from the some URL e.g. https://static.myDomain.com/ and not giving a damn about security
- Are there any downfalls to any of them?
- Can you share some of your personal info and wisdom about this topic ?