+ 5
is it good or bad to use PK publicly ?
it may be a stupid question, i read an article in tech republic, and found this `In a well-designed database, users never need to see a primary-key value. In fact, a user need never know the primary key even exists.` its obvious at first that we dont need to show (for example) user's pk in their profile, i can understand that. but what if we use it as a link to the user profile page ? ex. "example.com/user/pk_of-user_230" does it still count ? i mean we use pk publicly as part of the url mostly pk is indexed by default so search process would be faster, its pretty obvious why i would use it in such a case
15 Réponses
+ 5
Taste If security is the concerns, we don't want to reveal id on url string, not even any uuid there.
Let backend making the decision, if login user, render the profile page with user info, if not login, redirect to a public page eg login.html.
Using jwt token is one of the option to handle auth page, the other option is using session cookie.
We normally don't store any sensitive user data on jwt or session cookie too, server gets a _id from user db (which is a unique code that identify an user record) as jwt/session cookie data.
Whenever a user accesses bnk.com/account auth url, front-end would send jwt/session cookie on header, server would then decode it to obtain _id db reference and find user from user db (authentication).
If auth user is found, it would render the user info page, else server would redirect to a public page, eg login page.
User id is part of the user object that stored on database and never sent directly to frontend without passing authentication. No security is compromised.
+ 3
Taste
Did techrepublic explicitly say that it is bad?
By right (like you), I agree that PK shouldn't be exposed for public. But on the other hand, it is also inevitable even camouflaged, like here in SL, we can get a certain user's profile ID by visiting their profile and share the ID. But otherwise I'm not so sure.
Interesting topic BTW 👍
+ 3
Taste First of all, I would like to highlight that this is not PK, public key that use in authentication, it's just a page id.
Depends on the application, for public info pages like product id or book isdn, we can always expose the url with id, eg. market.com/products/1001
Multimedia sites expose user profile link with user id, so that the link is sharable among their community, it's the same case with Sololearn user link https://www.sololearn.com/Profile/4354920/
For secure application, for example bank account profile link, they don't expose the login user id at all. The url would stay unchanged, eg. mybank.com/account, with no id number, so zero traceability.
+ 2
Taste, Mirielle I did not say it is bad to use pk. I am just stating that it is not the best design choice.
1. SEO will favor more descriptive urls
2. People can guess random urls if it is just some number. If sololearn used pk in url. I can easily get random users by typing something like sololearn.com/profile/34.
3. It is not user-friendly. Users want personalized urls for their dashboard.
I can list many more reasons.
About not having a unique field. If there is no alternative use PK.
Also use PK when speed is important. Using PK is usually faster
+ 2
Mirielle The fact that Sololearn, stack overflow etc use it does not make it right or wrong. Here are a few problems with using integer primary keys in dashboard urls
1. There is a lack of peculiarity. To a computer it is a unique id but to a user it is just another dashboard url. If your site provides branding to users e.g dribbble it is not a good choice
https://dribbble.com/leoleung
What beats that when it comes to branding.
2. It is easily guessable.
https://www.sololearn.com/Profile/4425304/
I know there my pk is 4425304 and of course there is a 4425305 and 4425306 and so on. If I found an exploit in Sololearn and I wanted to do a mass attack this will be very bad(or good for the attacker).
3. It is not scalable. Sooner or later the integers may become large and a big int is needed. It is better to use a UUID instead of plain integers. Another unique field aside PK e.g username or email will be an advantage too.
Once again, it is not bad but it is hardly ever the best design choice.
+ 2
Calviղ how about put it in jwt token ? will it compromise the security ?
+ 2
yes, but we need a key to identify the user in the database to be persist inside the jwt.
since jwt is pretty much readable, storing a pk inside would "make it public" in some way, depend on how we store it.
so what should we do, in case we dont have any usable secondary key ?
sorry for asking too much, i rarely work with jwt, so i'm trying to figure out the best practice
+ 2
Taste like what i mentioned, we don't store sensitive information on jwt, only need to store a db _id which is basically useless for anyone to use it.
I would rather use session cookie, which is encrypted data, using serialize and deserialize methods to make it seamless.
+ 1
Instead of example.com/user/318 it is more readable to use example.com/user/Taste
Also you can index any column you like and if your username as a UNIQUE index it is better to use it to retrieve user.
+ 1
Ore
yes, i agree on using secondary key. but there's a case where we dont have/cant use unique column for the business key, in such a case of course we can generate one but how much difference does it make ?
Ipang
yeah, its pretty interesting to discuss. all i know just "its a common practice todo so", but never actually think why.
+ 1
what i usually do is store the session object (usually including the PK) in serverside, and only send back session-id as a cookie. so its pretty similar to yours
but we cant really apply this strategy for jwt, it'll break the statelessness of using jwt. it's possible to not including PK if we have secondary key to use, but there are times when we dont
+ 1
Taste jwt is stateless, the server maintain no state of the current user access, jwt token is needed to verify a token bearer's authorization every time access the server.
0
Taste using Pk is always the best.
When it comes to a public sites, that track users, articles, product etc, is always fast in making queries, than that of username etc
When you talk about security you can add a random phrase or number to each Pk before dispatching them to your URL,
Ex: example.com/profile/565yh2io
When you talk about readability you can add a slug field to it, ex: example.com/profile/565/username or example.com/profile/username-565
But you can still use only the username if you choose to. In this case username must be unique, but this is not to be compared to Pk fastness and efficiency in making queries,
Note: that it will always take more time to match queries using username that Pk, and what if your user's username is lengthy like haahahhahhahhahhahhahaismeisme and so, it will still take more time than usual.
I think Pk is the best except you just want a secret webpage with limited users.