Generate a unique id in react that persist - javascript

I need to keep a unique identifier for each client using my react app.
doing this will regenerate a random string (what I want) but does this on each refresh which is not what I want
const [id] = useState(Math.random().toString(36).substr(2, 8));
I've found uniqueId() form lodash but I'm afraid the id's won't be unique across multiple clients as it only give a unique Id and increment it at every call (1, 2, 3...)
const [id] = useState(_uniqueId());
Is there some kind of _uniqueId that generates a random string and also persist through page refresh?

I don't think there is a built-in or out-of-the-box solution that generates unique id in react that persist automatically. You have two problems to solve.
How to generate unique id. Which was already solved by using the uuid.
And how to persist it.
There are plenty of storage you can use depend on your need. Here's few of them where you can persist your data assuming you want it to be stored in client side.
LocalStorage
SessionStorage
Cookie
IndexedDB API
FileSystem
Again, it depends on your use case. So, carefully check them out which one fits on your requirement.

Another way to generate a temporary ID that would be the same for the same client, without storing it is to use browser fingerprinting.
For example, you can take user-agent, client timezone, and screen resolution, apply some hash function to them and call it an ID.
There are more advanced ways of fingerprinting that would result in less chance of two different users having the same ID, but it'll never be a 0% chance.
You also might want to use some libraries, such as https://github.com/fingerprintjs/fingerprintjs for this.

Related

Scalable Unique ID Function in Typescript

What is the methodology for generating a unique ID that minimizes the chance for an overlap?
for(let i = 0; i < <Arbitrary Limit>; i++)
generateID();
There are a few current solutions, but they are all roundabout ways of solving the problem.
Possible Solution 1:
Use a database to generate the new ID.
This does not work for me since I would like to do this in the frontend.
Possible Solution 2:
Use Math.random()*Math.floor(LIMIT), where LIMIT is a numeric value.
This does not work as minimizing the chance for overlap requires a large limit, and thus a massive ID. If working with hundreds of thousands of instances that need an ID, the chance increases greatly.
Possible Solution 3:
'_' + Math.random().toString(36).substr(2, 9);
This is close to working but I believe Math.random() is pseudo-random.
Possible Solution 4:
Date.now(). Date.getTime(), etc.
This does not work as generating [Date.now(), Date.now()] will cause the same ID. It arguably also needs a long ID to minimize overlap.
I do not require absolutely 0% chance of generating the same ID, I wish to minimize the chance as much as possible without:
Storing a count
Using 'other technology' (no database, no library, etc)
Making a massive ID
This preferrably should be scalabe, eg. This should work for 10 or 1000000 IDs.
Edit: Unique IDs generated locally and without need for communication across users of the frontend. Ex: A component needs to render many instances of the same class and needs a key to assign to it. Keys must be different and upon unmounting the component with its generated keys/instances is removed.
It seems you want to generate unique IDs entirely on the front-end and without relying on a backend at all or "storing a count". Then the solution depends, in part, on how many different users you expect will access your application's frontend during its lifetime, and the size of IDs depends on how much you're willing to tolerate the risk of collisions (assuming you're generating IDs at random); for that, see Birthday problem.
Then, depending on the size of IDs you choose, you generate the IDs at random using a cryptographic RNG (such as the function crypto.randomBytes), which is the closest available to "truly" random IDs.
On the other hand, if only few users will access your front end, but each one generates many unique IDs, then you can assign each user a unique value from a central database, because then each front-end computer can use that unique value as part of unique identifiers it generates and ensure that the identifiers are unique across the application without further contacting other computers or the central database.
Notice that there are other considerations as well: You should also consider whether just anyone should access the resource an ID identifies simply by knowing the ID (even without being logged in or authorized in some way). If not, then additional access control will be necessary.
For your purposes, you can try applying sequential IDs. If sequential IDs alone are not adequate, then you can try applying a reversible operation on sequential IDs. One example of this operation is technically called a "linear congruential generator with a power of 2 modulus", such as the ones described in the following pages:
How to sync a PRNG between C#/Unity and Python?
Algorithm or formula that can take an incrementing counter and make it appear uniquely random

Not allow localstorage to be changed by user

I use localstorage to store things like highscore in this game: http://wacky2048.ga/
If you inspect element and on the top navigation bar (where you see Elements ... Performance), then click the >> button, click Application, you can see all the localstorage items, and if you double click, you can change it. You may need to make a move and refresh.
A lot of people know this trick so the highscore becomes meaningless.
Is there any way to stop this? I store integers and JSON stringified things (in case you want to suggest a encoding method).
The better solution would be store the data in the server. But if you really want to use localstorage consider storing the JSON as a jwt token and encrypt it using a private key which user doesn't have access.
Also when your app access that data in the localstorage always check for validity. If the token is invalid, what you can do is re fetch the information from the server.
Like i said before this is more of a dumb approach. Storing data in the server would be a better solution.
Edit: To hide the private key you could use environment variables like NODE_ENV (this depends on the framework you are using)

What are the uniqueness guarantees of names generated with Firebase's push()/childByAutoID?

I'd like to use Firebase to make publicly-readable data whose location is difficult to guess. So, to give someone access to the data stored in "element [element ID = X]", I'd like to just send them "X", instead of sending them "X" along with a security token crafted to give them access to the element. Firebase's push() and childByAutoID seem like a natural fit: I can grant public read access to all individual elements, but deny public listing. My code will be blissfully free of token and random number generation. The automatically generated ID is supposed to be unique, and thus should be difficult to guess.
From looking at Firebase.js, it appears the first 8 characters of the automatically generated ID are based on the current timestamp, and the next 12 characters are randomly generated using Math.random(). I assume that the iOS framework does the same thing, and although I can't see the code, the library links to both SecRandomCopyBytes and arc4random.
For my purposes, this looks good enough, but has anyone seen guidance from Firebase on whether we can count on this behavior? I would hate to build code that assumes these names are relatively strong random strings and then have that assumption violated when I upgraded to a newer version of Firebase.
The purpose of the auto-generated IDs provided by Firebase is to allow the developer to create a chronologically ordered list in a distributed manner. It relies on Math.random and the timestamp to generate an ID unique to that client.
However, if you're going to use the auto IDs as security keys, it may not be the best idea depending on how secure you want your system to be. Math.random is not a cryptographically secure random number generator and since push() relies on it, the IDs generated by it aren't either.
The general concept of giving a user access to some data in Firebase if they know the key is a good one though. We have an example of using this type of security rule, but instead of using push IDs, we use a SHA-256 hash of the content itself (in this particular case, they are images). Hashing the content to generate the keys is more secure than relying on push() IDs.

Generating unique links that users can respond to

I'm building a web app that sends a person an email every time the person is handed a document (a physical piece of paper). The email contains a link that allows the user to request for a document pick up. The link should contain the user's id and the document's id. Is there a safe way to generate this link? Is this a good practice or are there other ways to implement such a thing?
I was thinking of using a hashing algorithm on the link, is this a good approach?
I'm using expressjs for my server side.
Thanks
Use for example node-uuid to create a UUID and pass it on the link, then store on the database to which document the UUID is linked to.
This solves several problems:
an attacker cannot guess UUIDs
there is no information on the UUID that can be extracted
I don't think hashing would help in this case, as we just need a way to create a one time token that cannot be guessed.
Hashing, obviously, will not include the document and the user's ID. So it's a bit confusing whether you want secure obfuscation (in which case you would want to use a hash algorithm (salt it if you're paranoid) that then quickly checks whether there is a document with the same ID and generates a new one to avoid document-ID mismatch) or that user and document IDs be included (in which case creating a format that includes both and a brief, usually session-dependent, ID to prevent document-ID mismatch will be just perfect).

Any technique on generate ID on js?

I want to make a WYSIWYG editor on web, and it supports multiple users for inputting data, but while the user is editing, many divs will create during the process, and each div should have an unique id to write in database, and use JS to generate. But the question is.... the id should be unique, how can I ensure the js code is unique, seems the js is execute in the client side, it may not occur....(the user may modify it using firebugs), also, the other client is editing the same document also, they may also use the same id, and the system will have a problem.....
Any ideas on that?
Give each client a large unique number range.
Consider maintaining a global variable based on a session variable/application variable and increment it or else you can use random number / datetime or both of them together.
Maybe like this :
id = Application variable + Session variable + (increment as per requirement)...
That will serve in both ways to give a unique solution..
In fact with known increment, your server can keep track of all the changes you make on client.
hope that helps.

Categories