User ids
What sub is, why it is different on every site by default, when you get the UNET user id instead, and what to key your own users table on.
When a person signs in, UNET tells your app who they are with a value called sub (the "subject"). It is the key your own user table should be built on. What sub is depends on the kind of app.
Two kinds of id
| Per-site id (pairwise) | The UNET user id (public) | |
|---|---|---|
What sub is | A stable value private to your site | The UNET user id, a number written as a string |
| Same person on another site | A different value | The same value |
| Can two sites tell they know the same person? | No | Yes |
| Default for | Sign-in-only apps | Apps that use the REST API |
The per-site id is derived from the person and from your site, so the same person always has the same sub on your site, never a value you can match against another site, and never the number that appears in the UNET API.
Which one your app gets
The kind is set when the app is created, and the console picks a default:
- Per-site when the app asks only for
openid,profileandoffline_access, and all its return URLs are on one host. - The UNET user id when the app has any REST API permission. The REST API shows real UNET user ids everywhere, so a per-site
subwould only make it harder to tell which user is "me". - If you choose a kind yourself under Advanced when you create the app, you get what you chose. A per-site id needs all return URLs on one host.
What counts as "your site"
- For a website with a server, the site is the registered domain. Two apps registered on the same domain see the same id for a person.
- For a single-page site or an app (a public app, which has no verified domain), the site is the App ID. Two such apps see different ids even for the same person.
What to key your table on
Key your users by sub, and only by sub.
usernamecan change. Show it, do not key on it.displayNameis free text. Show it, do not key on it.- There is no email address: UNET accounts have none. See Privacy.
const user = await unet.restore();
if (user) {
// your own table: key by user.sub, keep the name only as something to show
console.log(user.sub, user.username);
}On your server, take sub from a token you verified, never from what the browser sends. See Verify on your server.
Getting the UNET user id
If your app has a REST API permission, the API gives you the real id: Profile.id and the id of every author it returns. For example, to find your own:
const me = unet.getUser();
if (me?.username) {
const { profile } = await unet.api.profile(me.username); // needs content:read
console.log(profile.id);
}An app that signs in only for identity, with a per-site id, cannot get the UNET user id. That is by design: it is what keeps two sites from recognising the same person.
The avatar
The profile has the picture as avatarUrl, ready for an image tag. The raw avatar value is an internal storage key that older apps read; use avatarUrl. The userinfo endpoint also returns a standard picture claim with the same address. A person with a private account may not have their picture served to the public, so it can fail to load on your site.