Role value in JWT payload - javascript

I am trying to setup a json web token based api authentication that will be used for various role based authorization in APIs.
Can I keep role value as a payload in Tokens ? Is is Safe ? If Not What is the what to save role like admin or user or merchant etc after successful login ?

Yes, you can safely store whatever you like in a JWT, if you use the right type of token and name your custom field properly.
If the information is public and you just want to make sure the users can't change it to cheat, then simply use JWS and verify the token's signature. You can even do this client-side if the signature algorithm is based on a public key (RSA or ECDSA).
If the information to be stored on the token is not to be read by users, you can set up JWE (encrypted) tokens.
Your "role" field should be named according to the spec, using a collision-resistant name such as "com.yourdomainname.role" unless you are certain that your tokens will never be used by another client which also needs a "role" field with different semantics.

Related

is it okay to store a lot of variables inside the token object in NodeJS

Hey im implementing authentication using NodeJS expressJS mongoDB / React native
is it okay to have a lot of variables in the token object like this example ?
const token = jwt.sign(
{
userId: user._id,
isAdmin: user.isAdmin,
isBanned:user.banned.isBanned
},
process.env.TOKEN_KEY,
{
expiresIn: "24H",
}
);
I added the isBanned one so i can check for it directly when the token goes to the frontend so i won't have to fetch for the user data again to get it !
Is this the best way to check if the user is banned ?
and Finally is it okay to put up to 3 variables on the token
For security reasons, it's not safe to store users datas in a JSON Web Token.
Typically you should only store the minimum datas needed to identify your user, meannig an ID.
You should also, if possible, use an unpredictable ID because numeric IDs are predictable.
The best is to have an alphanumeric uniq ID.
If you need to get some extra information once you user login, you can easilly issue a request to your API to retrieve informations...
Don't forget that token is given to the client by the server after a successfull login to avoid authenticate user at each request, not for retrieving informations.

Swagger Authorization keys

In Swagger I have had problems to configure the authorizations.
In Available authorizations there are two fields to fill:
subscription_key (apiKey)Provide your cognitive services subscription key here.Name: Ocp-Apim-Subscription-Key
token (apiKey)
Provide an access token from the JWT returned by the STS of this region. Make sure to add the management scope to the token by adding the following query string to the STS URL: ?scope=speechservicesmanagement
I did not find it clear where I have to get this info.
Could someone help me?
The two paramters can be found as follows:
1. subscription_key parameter: this can be found in Azure portal> Navigate to the Speech service that you must have created (Cognitive Service) or see here to create new Speech service > use the value from Key1
Mine looks like below :
Things to remember :
The speech to text api (especially conversational api) is supported only in specific regions, I chose centralus.
The pricing tier should be S0 Standard to get the apis working (atleast for conversation apis)
2. token (apiKey) parameter :
You will need to generate the token by sending a post request to the speech service endpoint (see image above for location of endpoint url).
Add your subscription key as a header.
The post request will generate the access token as response
Things to remember :
As instructed in swagger, remember to add the query string of '?scope=speechservicesmanagement' to your endpoint url before generating the token.
ex: https://centralus.api.cognitive.microsoft.com/sts/v1.0/issuetoken?scope=speechservicesmanagement

password reset with jwt structure

I'm trying to write the password reset part of my authentication app. I chose to use JWT, node.js and express where I use the following logic: first, the user enters their email and a token is generated and sent to the user's mail in a password reset link. second, when the user presses the link a function is set to check if the token is correct and if it's still valid and third i have a function to save the new password to the database.
What I'm uncertain about is the second step where the token is supposed to be checked. Some tutorials say that you're supposed to save the token to your database and then compare the token in the link to the token in the database. But isn't the point with using JWT to not save anything to the database as reference? Shouldn't I just use jwt.verify to get the information saved in the token and then check for the user in the database and if it's still active?
Is this the correct way of using JWT? Or would you recommend me to use session instead of JWT?
There's a good suggestion in this answer. You can use some hash of your currently stored password value as part of the password reset JWT.
So the payload might contain { sub: user_id, exp: "now + 10 minutes", purpose: "password_reset", key: hash(hashed_password_from_db).substr(0, 6) }. This token can only be used successfully once.
There is a simple flaw in the use of JWT for reset password implementation.
From your current implementation, A user can generate the reset password link multiple times. So a user can have many active reset token in a given time.
Yes, JWT statelessness can be adopted, but it is not efficient in this case as you can have multiple tokens which can be used to reset the password even after the user has reset the password(depending on your approach).
I work in an organisation where testing and security is paramount. Your implementation would not be allowed.
The rule is that only one reset password link can be active at a time.
So JWT token is not the best option for us.
So what I do is to generate a random token saved in the DB(also with the current time). This token is to identify the user and, the time is to validate that the user is resetting withing a given time.
While the token is active, if a user decides to generate the token again, the former token is made inactive before a new one is generated.
The advantage of this method is that you can only have one active token at a time.
Lastly, JWT should be used if you don't mind a user having multiple active tokens/links at a time.

How do identify a new user using auth0-js WebAuth?

I'm trying to keep things simple and using auth0-js WebAuth to authenticate users. However, as there is a redirect involved, I'm not in control of the sign-up functionality at that point.
My specific use-case is to call a createUser graphql mutation using Graphcool to create a user in my database, but I only want to do this if the user is a new user, obviously.
MY QUESTION: Using auth0-js, is it possible to identify if a user is a new or existing user in my client application after the redirect from Auth0 back to my client application (assuming authentication is successful)?
There are two general approaches here, and both require you to persist the Auth0 token in local storage after receiving it. You can use a middleware for your GraphQL client that checks local storage for a token for every request and includes it as the Authorization: Bearer <token> header if present.
Let's now look at the two approaches.
Always try to create the user
Trying to create the user using the createUser mutation as soon as receiving the token is a fairly simple approach. This is how the mutation looks like:
mutation signUp($token: String!) {
createUser(authProvider: {
auth0: {
idToken: $token
}
}) {
id
}
}
Now, if the token is valid and matches the configuration of the Auth0 integration in Graphcool, there are two possible scenarios. Note, a token corresponds to a user if the auth0UserId it embeds matches.
there is already a registered user corresponding to the token. In this case, a GraphQL error Code 3023: CannotSignUpUserWithCredentialsExist will be returned (compare with the error reference documentation). In your application you can catch this error to proceed normally.
there is no registered user yet corresponding to the token. The createUser mutation will return id and all is good!
Check if the user is already signed in
If you have a more elaborate sign up flow, you might want to redirect your users to a sign up form, which is not really possible with the first approach. Instead, we can check if the currently used token corresponds to a registered user before proceeding. You can use the user query to do that:
query {
user {
id
}
}
Again, there are the same two scenarios as above:
there is already a registered user corresponding to the token. In this case, a the query returns a user object with the corresponding user id. So we can proceed the flow in the app normally.
there is no registered user yet corresponding to the token. The date returned from the user query will be null, so we need to call the createUser mutation, or switch to a sign up form or similar.
Compare this to this FAQ article in the Graphcool documentation.
In that case, the simplest solution will be to use auth0 rule and use context.stats.loginsCount field to detect the user is new or not.
https://auth0.com/docs/rules/references/context-object
You can add context.stats.loginsCount field value as a custom claim in the token using rule. Therefore, in your application, you can make a HTTP request to /userinfo endpoint to get the token data.
function (user, context, callback) {
const count=context.stats.loginsCount;
context.idToken["http://mynamespace/logincounts"] = count;
callback(null, user, context);
}
https://auth0.com/docs/api-auth/tutorials/adoption/scope-custom-claims
If the counts are equal to 1, create the user in your DB.

Trying to pull from a redis cache

I am new-ish to programming and am developing an app that has an email verification step. I'm hoping to take information from input fields, save it in a cache, then pull it from the cache when users get to verfication page through a UUID in the email.
My steps so far are to:
Save the username and password they enter in the registration page to a redis cache called 'users' with username, password, and UUID keys and values
Set a cookie for the user containing the UUID so that when they return I can pull the username and password from cache based on a UUID-based query from the cookie. (This is where I am having trouble, as I can't figure out how to search the redis cache by a field value).
Once the username and password can be accessed via the cache with the UUID, I will be inserting them into a Postgres DB.
Any thoughts? Or links to good redis documentation?
Another thought is, should I be using a hash rather than a set?
Cachers to the rescue please!
You don't search a redis server, you access a key. This is a critical piece of understanding. Also, as you aren't using it as a cache it can be useful to not refer to it as one.
The trick to designing your redis data structure is to determine how you will use it when you pull data from it and store it that way, not store then figure it out.
Here is how, if I had to, I'd structure what you are doing in redis:
For a given UUID. Create a Redis hash with the UUID as the name of the hash. The hash will have the key/value pairs (or members) of username, password (please at least store it encrypted), and any other key/value pairs you use in the session.
This allows you to access precisely the data you are after, and you can look it up with the UUID. Basically the UUID identifies a particular collection of data.

Categories