How to protect image URL from unauthenticated access in angular - javascript

In my angular app, it has no,of image urls, how can protect those url from unauthorized access? for example the url can be copied and paste in to any browser(without authentication) or send anywhere.
so it makes any one can accessible. but I require to protect, as well i need to provide the access until the user logged in. is there any specific approach for angular or in general?
needs the advice. thanks in advance.

One way to overcome this is pass the token in your image url and validate the token from the backend. If its successful return the image.
www.samplesite.com/myImageUrl?token=123
The image tag will look something like this.
< img src="https://www.samplesite.com/myImageUrl?token=123" alt="sample">

For unauthorized access, you can change your server settings to only serve static resources from a specific domain, block all other domain requests.
For images after login, you will have to do that by code and that would be a lot of work. Since, you will have to add a boolean to check if user has logged-in or not.

Option 1:
You can display the image as blob, like this:
var location = 'https://images.unsplash.com/photo-1474511320723-9a56873867b5?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80';
fetch(location).then(response => response.blob()).then(blob => {
var url = URL.createObjectURL(blob);
var image = document.createElement('img');
image.src = url;
document.body.appendChild(image);
// your url will look like this:
// blob:https://example.com/f347bbac-af35-40a8-ac2b-daf639faf2db
// this url cannot be used on another domain
console.log(url);
});
Option 2:
Move all of the images to the place that cannot be accessed directly. After signing in, whenever you need to display an image, just make a request to server. Then, server will return a file for the request.
Your_project
|_ wwwroot (public)
|_ Your image folder (private)
|__ folder01
|____ image01.png
|____ image02.png
Reference: Returning a file to View/Download in ASP.NET MVC

Related

How do I save file urls on javascript?

I'm creating a webapp on which I load and display images.
I want to have a feature on which the user can save the images they loaded so they can reload them on future sessions without having to manually set up everything again.
For doing this I have thought of storing the url from the files, but it looks like I can't access the url of files because of security on most browsers. Is there anything I can do to save the url of the files, or something similar so I can reload the files on future sessions?
It will ideally allow to store many files, so saving the local paths to the images is best so it doesn't consume much space.
For the app I'm using angular and tauri.
Anyone can help? Thanks a lot in advance!
EDIT: I found out there is a way to do this on tauri with the dialog module you can find here: https://tauri.studio/api/js/modules/dialog more info here:https://github.com/tauri-apps/wry/issues/87
If anyone reads this and is using electron instead of tauri I've read that the File Object gets added a path property, so you can get it from there.
Thanks everyone for the help!
For storing user-downloaded images, you need a backend. If you don't want to run one, you can try to store images as data: urls in cookies or local storage, but it won't work well.
I recently did one functionality for download file and sharing the code here
downloadFile(data, fileName) {
const urlBlob = window.URL.createObjectURL(data);
const link = document.createElement('a');
link.href = urlBlob;
link.setAttribute('download', fileName);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
Data stands for your file path or file URL and
fileName stands for File save with name as
you want
Found the answer!
I found out there is a way to do this on tauri with the dialog module you can find here: https://tauri.studio/api/js/modules/dialog more info here:https://github.com/tauri-apps/wry/issues/87
If anyone reads this and is using electron instead of tauri I've read that the File Object gets added a path property, so you can get it from there.
You can use cookies to store data. Users can block or remove cookies, but most users (as most users use Chrome) have cookies enabled by default.
You can store a cookie by doing
document.imageurl = "http://example.com";
and access it using
console.log(document.imageurl);
or something similar (variable is stored at document.imageurl)
The variable will stay there when the page is reloaded.

How to find out which parent URL called my script?

I have created a page for a web banner under http://example.com/banner, I'm sending this link to publisher websites and pay them to run it.
However, some publishers run, some are not and I'd like to find which parent URL'S called for this page or where did the click come from. Generally, they are putting this URL in an iframe to serve it.
(Many pages doesn't pass referral parameter.)
I've tried different approaches with JS and PHP but as you might guess I'm getting http://example.com/banner as the parent URL.
Is there a way to know the parent URL from a different domain with PHP, JS or any other piece of code? I have a list of publishers but I also need to know which websites running the banner except for those sites.
To make it more clear here is a schema:
MY PAGE WITH BANNER > MY PUBLISHER WEBSITE > USER VISITING THE
PUBLISHER
I don't want to get IP of the user visiting my publisher's website or my page's
URL. I want to see URL of my publisher's website which is in between.
Since this is my web server I can read access logs, error logs etc. without issues.
I'm open to any suggestions.
Thanks!
You could try this, host a javascript file on your server.
Then they would place the script anywhere they want to put the banner:
<script src="//yoursite.com/banner.js"></script>
You could use params in that URL to then serve custom js.
Then fundamentally the code would look something like the following which injects the banner into the DOM where ever the script is placed. You get the sites URL from window.location.href and then send it as a param when requesting the image. (You could also use cookies etc)
<script>
// inject an anchoring element
document.write('<div class="banner_ad"></div>');
// find it
var parentDiv = document.getElementsByClassName("banner_ad");
// create the img/banner, notice the site param
var banner = document.createElement("img");
banner.src = 'http://via.placeholder.com/350x150?site=' + encodeURI(window.location.href);
// loop over the parent elements of each anchoring element
for (var i = 0, len = parentDiv.length; i < len; i++) {
// create the link
var link = document.createElement('a');
link.appendChild(banner);
link.setAttribute('title', 'Ads by Foobar');
link.setAttribute('href', 'http://example.com');
// inject the link and img
parentDiv[i].parentNode.appendChild(link);
}
</script>
Then server-side, look for the $_GET['site'] param.
It's not foolproof, nothing is.

Uploading files to Azure storage container from html5 directly

For my scenario, I am trying to allow a user to drag and drop files to a webpage using javascript that would be uploaded to a container, upload the files similar to how wordpress media uploading works from the administrative side. The problem I am having is that I found code for creating a SAS url for the container,
//Set the expiry time and permissions for the container.
//In this case no start time is specified, so the shared access signature becomes valid immediately.
SharedAccessBlobPolicy sasConstraints = new SharedAccessBlobPolicy();
sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24);
sasConstraints.Permissions = SharedAccessBlobPermissions.Write;
//Generate the shared access signature on the container, setting the constraints directly on the signature.
string sasContainerToken = container.GetSharedAccessSignature(sasConstraints);
//Return the URI string for the container, including the SAS token.
return container.Uri + sasContainerToken;
but all of the examples I found seem to indicate that I have to generate a sas url for each blob
Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
//Get a reference to a container to use for the sample code, and create it if it does not exist.
Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer container = blobClient.GetContainerReference(containerName);
container.CreateIfNotExists();
//Create a new stored access policy and define its constraints.
Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPolicy sharedPolicy = new Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPolicy()
{
SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(10),
Permissions = Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPermissions.Write
};
//Get the container's existing permissions.
Microsoft.WindowsAzure.Storage.Blob.BlobContainerPermissions permissions = container.GetPermissions();//new Microsoft.WindowsAzure.Storage.Blob.BlobContainerPermissions();
Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob blob = container.GetBlockBlobReference(fileName);
return blob.Uri.AbsoluteUri + blob.GetSharedAccessSignature(sharedPolicy);
instead as if I am uploading one file.
An administrator can upload any number of files, so to have to generate a blob sas via web api call for each one of these files seems to be very inefficient. I would prefer to generate a SAS for the container and allow the user to upload to that container for a specified time, say 3 hours. Also, I would like to use chunking to upload each file. Would this be possible or would I have to generate a blob sas url for each file?
An administrator can upload any number of files, so to have to
generate a blob sas via web api call for each one of these files seems
to be very inefficient. I would prefer to generate a SAS for the
container and allow the user to upload to that container for a
specified time, say 3 hours.
It is certainly possible. When you create a SAS on a blob container with Write permission (for uploading purpose), same can be used for uploading multiple blobs in that container. You just have to construct blob URI based on the file being uploaded and append the SAS token. So for example, you created a SAS token for mycontainer container in myaccount storage account and uploading a file myfile.png, your SAS URL would be https://myaccount.blob.core.windows.net/mycontainer/myfile.png?SAS-Token.
I noticed in your code that you're returning container URI with SAS token. In this case, you just have to insert the file name after container name to get blob upload URI.
Also, I would like to use chunking to upload each file.
It is again possible. I wrote a few blog posts about this some time back which you may find useful:
http://gauravmantri.com/2013/02/16/uploading-large-files-in-windows-azure-blob-storage-using-shared-access-signature-html-and-javascript/ (This was written before CORS support in Azure Storage so please ignore my comments about CORS in the post).
http://gauravmantri.com/2013/12/01/windows-azure-storage-and-cors-lets-have-some-fun/

InAngularJs, ng-src for img doesn't show for local files

I have an ng-repeat that, among other thing, outputs on image:
<div class="installation" get-products install-index="{{$index}}" ng-repeat="installation in installations track by $index">
...
<img ng-src="{{installation.logo}}" />
...
</div>
When my app starts it downloads needed images and stores their location in a local database. When the page is viewed the installations are populated:
<div class="installation ng-scope" ng-repeat="installation in installations track by $index" install-index="43" get-products="">
...
<img src="C:/Users/.../AppData/Local/Packages/.../LocalState/installations/.../...png" ng-src="C:/Users/.../AppData/Local/Packages/.../LocalState/installations/.../...png">
...
</div>
(dots used to hide person and client data)
If I paste the src location into my browser I see the image so I know it's saved at that location. However, in my app it's not showing. This is a constant issue through the app with the downloaded files. I know the image are in the correct area and the src location is correct but none of them show.
--- EDIT ---
I do have white listing applied as I was getting an unsafe for file:///. Also, when I was using a relative path it was working fine. I had a preloaded database that pointed to file inside the app files.
I don't think it's an access issue since I have a .db file at the same location that all my data is being pulled from.
--- EDIT ---
I set it as file:///C:/... and I'm having the same issue.
I also tried file:///C:/... , http://localhost/..., http://localhost:/..., http://localhost:C/..., C:/..., and file:///.... None of witch give me anything. The first two localhost items do give me a broken image icon, that's about it. I'm not running a local server, just thought I'd try it.
You can do this in two different ways:
1) Use the file protocol
2) use a local host server to store the picture and access it from the local host
for security reasons you cannot use your file system path for images. you shouldn't even use it at all, because when your app gets hosted, you wouldn't be accessing the image via such paths.
method 1:
just add file:/// in place of the c:/. file is the protocol for your file system, just as http or HTTPS is a web protocol.
NB: I haven't tested or used this before so I'm not really certain. I'm posting this from a small mobile device. but I believe it should work.
method 2:
start your wampserver or python server or any local server you have. put the image in a folder where your server can access (if wampserver, this would be a folder or directory in your WWW). say the name of the folder is "my_images" and your wampserver is running on localhost.. you can access the image like so:
http://localhost/my_images/image_name
use this path for your ng-src.
Because I Cordova File and Windows weren't playing nice using the call for cordova.file.dataDirectory didn't work. Instead I used the fs object returned by window.requestFileSystem(...,function(fs){...});
When generating my save to path as well as the path to create directories and location data I used fs.winpath which returned C:/.... The web (which Cordova basically is) won't allow you to have access to local files not associated with the site/apps structure, which is now obvious.
I dug in to the fs object and found fs.root.nativeURL points to ms-appdata:///local/. Switching everything over to this still downloaded all files and directories to the same location but stored that to the database as the file location. When the app loaded the ms-appdata path instead of the C:/ path the images displayed.
oh, a Cordova app.. why don't you place the file in an images folder In your project. since all files will be loaded using index.html (I assume). you can easily refer to the file relative to the location of index.html. how I would normally organize my project is that, my index.html and folders containing resources like js, CSS etc would be on thesame level, so I can easily get the image files using ng-src="img/image_name". so I could have a structure like this
index.HTML
img
..image_name.ext
..image2.ext
css
..style.css test it in a browser location if it works, it will work on the device. Cordova would know how to translate d into something it can recognise.
This is some sample code, i quickly put together. I tested it and it worked. Firstly i create a directory using file plugin and then download to this directory using file transfer. Replace the url parameter of file transfer with the url you wish to download from.
$ionicPlatform.ready(function() {
$cordovaFile.createDir(cordova.file.externalDataDirectory,
file_location,false).then(
function(success){
return success;
},function(error){
return error;
}).then(function(value){
var url = material.file_uri;
var targetPath = cordova.file.externalDataDirectory
+ "/" +file_location + "/" + file_name;
var trustHosts = true
var options = {};
$cordovaFileTransfer.download(url, targetPath, options, trustHosts)
.then(function(result) {
console.log(result)
}, function(err) {
console.log(err)
}, function (progress) {
$timeout(function () {
console.log(Math.floor((progress.loaded / progress.total) * 100));
})
});
})
})

Use multiple canvas URLs in one Facebook app

I am trying to host my web app on different domains. But I will receive errors like:
Given URL is not allowed by the Application configuration.: One or more of the given URLs is not allowed by the App's settings. It must match the Website URL or Canvas URL, or the domain must be a subdomain of one of the App's domains.
However it seems I can only set one canvas URL and secure canvas URL in my Facebook settings page. Is it possible to host my web app on different domains? Thank you very much!
If you can host a single php file (although it doesn't contain php at all, only javascript) on a SSL host you can do it. I wrote a blog post on how I did it using 2 app sharing the same canvas url.
A SSL host is mandatory for this to work. Also shared certificates work.
Short story long in the index.php file you need to:
var urlString=document.referrer;
var pageNameN = "?p="; //this is specific to the first application
var pageNameZ = "?url=";// this is specific to the second application
var indexN = urlString.indexOf(pageNameN);// and get its index.
var indexZ = urlString.indexOf(pageNameZ);// and get its index.
if(indexN != -1){
var resN = urlString.substring(indexN);
location.href = "https://FIRST_APPLICATION_URL/"+resN; }
else {
if(indexZ != -1){
var resZ = urlString.substring(indexZ);
location.href = "https://SECOND_APPLICATION_URL"+resZ; }
}
You catch the request and than split it depending on the requesting url.
In the post you also find the index.php file I used in my case you can download, too.

Categories

Resources