only allow access to url in certain locations (qr codes) - javascript

My company has a social networking platform that is accessed via a URL.
We are trying to find a way to advertise our URL in sports stores, with access to our site only possible if you come to the store - we do not want the sharing of the URL to anyone, anywhere.
We have considered QR codes and wonder if it's possible our site can only be accessed when a provided QR code is scanned.
Please let me know if you have any suggestions.

You are basically looking for keys/ access codes that give your customers access to a site.
Those might have to be on a per-user basis, as otherwise one might just leak an access code for the whole public to use.
If sharing keys should be disallowed:
You need a database (sql) to store your cusstomers' information.
Depending on how you generate a key (dynamically, by a set of rules or randomly, using a catalogue of valid keys) you might need a further table to store the keys separately (in case you choose the more secure option of generating a predefined set of random keys)
You can then include those keys in your QR Codes' target URL like www.example.com?key=1jh303u or something similar.
(This means of course that you have to produce customized QR Codes, which in turn means they cannot be printex as a standard mass-produced offset job, but as a customized digital print - so you'd have to send all the different generated QR Codes to your printer)
Once the user visits this URL containing the query string, your site can then check to see if the key is a) valid (in the table) and b) unused, by taking the &_GET["key"] variable and querying the database.
If the key is invalid, output an "access denied" page.
If the key exists but has already been checked in, you can use a user-based login system to handle the login.
If the key is valid and hasn't been used yet, you can output your exclusive content at last.
If it doesn't matter whether people will be able to share their key, you don't need a database at all. You could build a keygen which creates keys after a certain destinct pattern, and use that same set of rules to validate against the entered key.

Related

Creating temp URLs in single page applications

In my react based single page application, my page is divided in two panes.
Left Pane: Filter Panel.
Right Pane: Grid (table containing data that passes through applied filters)
In summary, I have an application that looks very similar to amazon.com. By default, when user hits an application's root endpoint (/) in the browser, I fetch last 7 days of data from the server and show it inside the grid.
Filter panel has couple of filters (e.g. time filter to fetch data that falls inside specified time interval, Ids to search data with specific id etc.) and a search button attached in the header of filter panel. Hitting search button makes a post call to a server by giving selected filters inside post form body, server returns back data that matches filters passed and my frontend application displays this data returned back from the server inside grid.
Now, when someone hits search button in the filter panel I want to reflect selected filters in the query parameter of the URL, because it will help me to share these URLs with other users of my website, so that they can see filters I applied and see data inside the grid matching these filters only.
Problem here is, if on search button click, I use http get with query parameters, I will endup breaking application because of limit imposed on URL length by different browsers.
Please suggest me correct solution to create such URLs that will help me to set the selected filters in the filter panel without causing any side effect in my application.
Possible solution: Considering the fact that we cannot directly add plain strings in query parameter because of URL length limitation from different browsers (Note: Specification does not limit the length of an HTTP Get request but different browsers implement their own limitations), we can use something like message digest or hash (convert input of arbitrary length into an output of fixed length) and save it in DB for server to understand the request and serve content back. This is just a thought, I am not sure whether this is an ideal solution to this problem.
Behavior of other heavily used websites:
amazon.com, newegg.com -> uses hashed urls.
kayak.com -> since they have very well defined keywords, they use
short forms like IN for INDIA, BLR for Bangalore etc. and combine
this with negation logic to further optimize maximum url length. Not
checked but this will ideally break after large selection of filters.
flipkart.com -> appends strings directly to query parameters and breaks
after limit is breached. verified this.
In response to #cauchy's answer, we need to make a distinction between hashing and encryption.
Hashing
Hashes are by necessity irreversible. In order to map the hash to the specific filter combination, you would either need to
hash each permutation of filters on the server for every request to try matching the requested hash (computationally intensive) or
store a map of hash to filter combination on the server (memory intensive).
For the vast majority of cases, option 1 is going to be too slow. Depending on the number of filters and options, option B may require a sizable map, but it's still your best option.
Encryption
In this scheme, the server would send its public key to the client, then the client could use that to encrypt its filter options. The server would then decrypt the encrypted data with its private key. This is good, but your encrypted data will not be fixed length. So, as more options are selected, you run into the same problem of indeterminate parameter length.
Thus, in order to ensure your URL is short for any number of filters and options, you will need to maintain a mapping of hash->selection on the server.
How should we handle permanent vs temporary links?
You mentioned in your comment above
If we use some persistent store to save the mapping between this hash to actual filters, we would ideally want to segregate long-lived "permalinks" from short-lived ephemeral URLs, and use that understanding to efficiently expire the short-lived hashes.
You likely have a service on the server that handles all of the filters that you support in your application. The trick here is letting that service also manage the hashmap. As more filters and options are added/removed, the service will need to re-hash each permutation of filter selections.
If you need strong support for permalinks, then whenever you remove filters or options, you'll want to maintain the "expired" hashes and change their mapping to point to a reasonable alternative hash.
When do we update hashes in our DB?
There are lots of options, but I would generally prefer build time. If you're using a CI solution like Jenkins, Travis, AWS CodePipeline, etc., then you can add a build step to update your DB. Basically, you're going to...
Keep a persistent record of all the existing supported filters.
On build, check to see if there are any new filters. If so...
Add those filters to the record from step 1.
Hash all new filter permutations (just those that include your new filters) and store those in the hash DB
Check to see if any filters have been removed. If so...
Remove those filters from the record from step 1.
Find all the hashes for permutations that include those filters and either...
remove those hashes from the DB (weak permalinks), or
Point that hash to a reasonable alternative hash in the DB (strong permalinks)
Lets analyse your problem and the solution possible.
Problem : You want a URL which has information about the filter applied so that when you share that URL user doesn't land on arbitrary page.
Solutions:
1) Append filter applied with URL. To achieve this you will need to shorten the key of type of filter and the value of filter so that Length of URL don't exceed much for each filter.
Drawback: This is not most reliable solution as the number of filter increase URL length has to increase no other option.
2) Append a unique key of filter applied(hash) with URL. To achieve this you will need to do some changes on server and client both. On client side you will need a encoding algorithm which convert filter applied to unique hash. On server side you will need decoding algorithm which convert unique hash to filter applied. SO now client whenever a URL like this is hit you can make a POST api call which take this hash give you the array of filter applied or on client side only put the logic to convert this hash.
Do all this in componentWillMount to avoid any side effect.
I think 2nd solution is scalable and efficient in almost all cases.

How can I define a unique URL for a user without using their ID?

Good evening guys, so I would like to know how jsfiddle.net does to save the content of the page in a unique url? For example: jsfiddle.net/u5jm5jq8. I was wondering how can I do this with javascript. Because you do not necessarily have to be logged in to save and be generated the unique url.
This is known as a hash ID, a unique identifier typically generated from a unique attribute like an entity's primary key in the database. Hash IDs are usually shorter than typical hashes created by cryptographic hashing algorithms such as MD5 or SHA-256 and, unlike these, hash IDs are usually reversible, meaning we can decode the original value. They reduce exposure of your application's internal implementation which can improve security.
Check out hashids.org. This site provides implementations in various programming languages.
Unless you have a good reason to do otherwise, avoid generating the hash IDs in the client. By creating the hash IDs on the server, you can guarantee that the IDs are unique and consistent with identifiers used by whatever mechanism your application stores data through.
Edit for comment - here's the procedure you might follow to use a hash ID in a URL:
Let's assume that we're using hash IDs to create links to user profiles. When we generate a page that contains a link to a profile, our application will:
Convert the user ID (ex. 5) to a hash ID (ex. 3ac4jx60)
Show the page with a link like http://example.com/user/3ac4jx60
If the site visitor clicks that link, the application will receive the request and:
Decode the hash ID in the URL to get the user ID (3ac4jx60 → 5)
Use the user ID to fetch the appropriate record and display the user's profile

Can we use algolia search with access level permissions

We are looking to use Algolia Search for an application. We like the convenience of Algolia but are stuck on one point. We have custom user groups and each user group can only see a subset of the records. When we are pushing records to Algolia all the records show up. How do we pair that with our custom logic of specific users can see specific records and we dont those to show up on the search lists.
The best way to handle this use case is to encode the permission information directly inside your records (like a group or a user). You can for example add a permission array on your record:
"permission": ["group1", "user42"]
You then just need to add this permission attribute in the list of attributes for faceting and apply the restriction in your query via a facetFilters argument.
I would also recommend to use the secured-API key feature that allows to apply this restriction in a secure way even if the query come from a browser or mobile app. A HMAC-SHA 256 signature is computed in your backend between the API key and the restriction to ensure no-one can change this restriction.

Cross Domain Conversion Tracking

SETUP:
Having a few different information sites/domains about my products and one single site/domain shop-site where you the purchase, checkout and so on happens, I'm having troubles to find a proper solution for a comprehensive tracking of all the pages including the conversion tracking.
IDEAL:
What I want is to get reports seperated for each site (shop-site as well as information-sites), but add some conversion tracking. Ideal would be to be able to track a conversion when the user gets to the checkout process, so that I can see it in the statistics of the shop-site as well as on the site that referred to this sale/conversion and maybe even a funnel visualisation for the whole action.
WHAT I ALREADY GOT:
I already set up statistics for each site/domain. I do have set events for a referal to the shop-site as well as an event when the user checks out.
WHAT I TRIED:
I set up cross domain tracking for one of my information-sites and the shop-site, so now the events show up in that single property.
Unfortunately thats not the statistic I intend to get, as the whole data got consolidated from those 2 properties. Also it made the tracking goal/conversion only accessible for that single property, while I can't distinguish between a conversion made originally from this site or one of the others.
Is it possible to achieve what I actually intend to do or what's the proper way to track such a setup??
You can either use an additional tracker (so you have one UA id that goes in your "normal" domain, one that goes in your shpooing site and one that is placed on both sites) - you'd still have both pages tracked in separate properties, but you'd have one rollup property that tracks all your sites. This might however unwanted complexity if you use event tracking etc (since you'd have to see to it that events are always pushed to the correct tracker).
An easier solutions is via views/profiles - use the same UA id for both sites; create views based on domain name (filter in the admin section) to track each site separately; for the common data view that display data from both sites create a filter that includes the hostname in the reports so you can tell both sites apart in the report.

Efficient way to pass arrays in url

I am building a webapp and have a few arrays that I would like to pass through the URL in order to make the results of my application easily sharable.
Is there an efficient way to do this? I know a lot of websites (like youtube) use some sort of encoding to make their URLs shorter, would that be an option here?
Thanks in advance!
What I suspect you're asking is you have some page where the user can alter information, etc, and you want a way to create a URL on the fly with that information so it can easily be accessed again. I've listed two approaches here:
Use the query string. On your page you can have a button saying "save" that produces a URL with info about what the user did. For example, if I have a webpage where all I do is put my name in and select a color, I can encode that as http://my-website.com/page?name=John_Doe&color=red. Then, if I visit that link, your page could access the query object in JavaScript and load a page with the name and color field already set.
An approach for the "YouTube-style" URLs would be to create a hash of the relevant information corresponding to the page. For example, if I were creating a service for users to store plaintext files. These files are to have the following attributes: title, date, name, and body. We can create a hash of the string hash_string = someHashFunction(title+date+name).
Of course, this is a very naive hashing scheme, but something like this may be what you are looking for. Following this, your URL would be something like http://my-website.com/hash_string. The key here is not only creating these URLs, but having a means to route requests on the server side to the page corresponding to the hash_string.

Categories

Resources