password authentication token / Nodejs - Express JWT - javascript

I'm having trouble logging into the server to do the authentication tests for my JWT password token, it claims problem
no " required:jwt({"
grateful to whoever helps me
user side of authentication
I tried changing the commas but the problem persisted I believe it is something deeper

You should require the library with a different syntax, reading documentation:
const { expressjwt: jwt } = require("express-jwt")
Also, it looks that the algorithms property is a required option. Therefore, on line 20 and 25 of your code, you want to write something like:
jwt({secret:'secret', algorithms: ["HS256"], userProperty: 'payload', getToken: getTokenFromHeader)
The above example just works. Of course you should choose the right strategy and the right algorithm for a strong authentication.

const { expressjwt: jwt } = require("express-jwt");

Related

How to use bcrypt to encrypt a date and decrypt it for comparison?

I am sending a token to user email like below and using bcrypt for this as an encrypt/decrypt mechanism.
const token = await bcrypt.hash(joinDate, 10);
When the user clicks on the link in email, I get the above token back as that token is a part of
/api/unsubscribe?userId="abcd"&token="token_that_was_generated_using_bcrypt_and_sent_to_user"
const {userId, token} = req.query;
In the api, I am comparing joinDate obtained from database vs token sent by req.query but it never matches.
const joinDate = user.joinDate.toString();
const tokenValidated = await bcrypt.compare(joinDate, token)//this is always false although us generated from same joinDate field
Why is tokenValidated always false although it was generated using the same field joinDate?
Your use of bcrypt is not secure. Anyone can brute-force a few hundred or a few thousand dates and cause any user to become unsubscribed.
I assume your motivation is to avoid having to create a new table in your database and store a random token for every email you've sent out.
If so, the proper tool to use is HMAC.
Your URL should be of the form: /api/unsubscribe?userId=abcd&mac=....
Come up with a secret key known only to your server. This secret key will be used to create and authenticate all unsubscribe requests. Only use this key for authenticating unsubscribe requests.
Perform HMAC-SHA512 on the user id, with the HMAC output truncated to 128 bits. Then base64-encode the 128 bits and set it as the mac parameter in the URL.
HMAC means to create a hash-based message authentication code, which will confirm to your server that it must have created and emailed out that 'mac'.
Now, your server can authenticate each response, because only someone with knowledge of the server's secret key can produce a valid unsubscribe link.
Your logic of using bcrypt for hash and verifying on the other end should work. The only possible thing that can prevent it from working is either:
1 - the joinDate here: const token = await bcrypt.hash(joinDate, 10);
is not ===
to joinDate here:const tokenValidated = await bcrypt.compare(joinDate, token)
( maybe differes in ", ' or different format orsomething )
2 - or the token is kinda different in ' or " when passing through / read from queryparam; (e.g. you token is going "'token_that_was_generated_using_bcrypt_and_sent_to_user'" for comparison.)

How can I make a script in python to reload an app in qlik cloud

At this moment I'm trying to reload a Qlik app through a python script, but I had a few problems, I'm gonna explain the things I already tested, but if someone knows how can I solve that, I will appreciate it a lot
The first thing I tried, was the "reloads API" from qlik, to do this you have to send a request with the app id, and with the parameter "Partial" true or false, but even more important, you have to send with this request a JSON web token, so I was searching how to obtain the jwt of qlik and I found this page: "https://qlik.dev/tutorials/create-signed-tokens-for-jwt-authorization", I created all as the page said, and finally I make this code in javascript to test, but this doesn't work:
const fs = require('fs');
const uid = require('uid-safe');
const jwt = require('jsonwebtoken');
const https = require('https')
const payload = {
jti: uid.sync(32), // 32 bytes random string
sub: '(id of my user that appears in assignment users)',
subType: 'user',
name: '(Name of my user)',
email: '(email of my user)',
email_verified: true,
};
const privateKey = fs.readFileSync("path/certificate.pem");
// I don't know the meaning of that 'kid and issuer have to match with the IDP config'
// audience has to be qlik.API/jwt-login-session
const signingOptions = {
keyid: I put = 'my-custom-jwt',
algorithm: I put = 'RS256',
issuer: '(hostname)',
audience: I put = 'qlik.api/login/jwt-session',
};
const myToken = jwt.sign(payload, privateKey, signingOptions);
const qlikUrl = "(hostname)"
const data = JSON.stringify({"appId": "(appId)", "partial": true})
const options = {
hostname: qlikUrl,
port: 443,
path: '/api/v1/reloads',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer '+ myToken
}
}
https.request(options)
req.write(data)
The second thing I did was, try to use the "qsAPI" library of python to connect to my qlik and reload an app specifying their id by a method of this library, but I don't understand what I have to put here, and in the documentation, doesn't say nothing about what's the meaning of the parameters, except ('hostname'). The problem is in the method to do the connection because I have to do this:
qrs = qsAPI.QRS(proxy='hostname', user=('yor_domain', 'username', 'password'))
I say that because if I go to the python IDE, this show which parameters I have to put, and these are different, now I have to put this:
qrs = qsAPI.QRS(proxy='hostname', user=('userDirectory', 'userId', 'password'))
I don't know where I can find the user directory because I don't know
what it is.
The user id (I'm guessing it's the user id that appears in "mapping
users").
The "password", is no problem
But still have an opportunity, because I can connect to Qlik through python if I find where I can download the certificate authentication of a user, but I don't know where is it in qlik cloud.
Can someone help me, please
I havent tried with Python (only with JS/TS) but the approach should be the same.
Couple of things:
imo instead of web token you can try with API Key (for a start). Managing API keys -> Generating an API key from the hub.
the second point is that qsAPI seems to be for Qlik Sense Enterprise on Windows and not for SaaS.
the only Python lib dedicated for Qlik SaaS (that im aware of) is qsaas. Havent used it myself ... just found it on GH
and a bit of a warning regarding the partial: true. Please make sure that you really have to use partial reload. Partial reloads have a specific use case and be careful when using them ... just saying :)
I finally have the solution of that as Stefan Stoichev said before publishing this post, the qsApi seems to be a python library for Qlik Sense Enterprise on Windows, and the correct library for the Qlik Cloud is qsaas, but I'm going to explain every step because I don't want that any person of this world suffer this.
First of all, you have to create an API KEY, in Qlik Cloud, IMPORTANT, you have to save the api_key code that appears in a green text box when you created successfully your API KEY, save this as your dear friend because you will need this code in the future
Subsequently, you have to create a new python code as this:
from qsaas.qsaas import Tenant
import JSON
api_key = <API_KEY>
q = Tenant(api_key=api_key, tenant=<hostname>,
tenant_id=<tenant_id>)
q.post('reloads', json.dumps({'appId': 'dbf3e4ce-c6b3-4190-876c-c443a8691fa6'})))
Don't worry my dear friend if you don't know where is it, the 'hostname' and the 'tenant_id' are in qlik cloud, here is a little tutorial for you:
First login to your qlik
Then click on your profile photo
Click in about, and there you have these two data information

How do i set a cookie on different node js routes?

I'm developing a user based project, using node ( express, mongoose etc. )
I currently use JWT and the token has the user id in it, I know how to send a cookie when someone logs in, but I don't know how to make the cookie work on all routes, like basically when a user is logged in and goes on route /test the cookie is still there.
I think what I'm trying to achieve is called "session/cookie based authentication", could be wrong idk.
Once you set a cookie, from within any route, with
const myCookieValue = 'whatever'
res.cookie('myCookieName', myCookieValue, {
maxAge: 3600*1000, /* one hour */
httpOnly: true
})
you can retrieve its value, from within any route, with
const myCookieValue = req.cookies.myCookieName || 'yo! no cookie! something is wrong!'
The cookie-parser package makes this possible, handling the gnarliness of the the HTTP header for you.

how to fix tsr-detect-possible-timing-attacks potential timing attacks

I have code like this:
if (!confirmPassword) {
errors.confirmPassword = DefaultValidateErrors.confirmPassword;
} else if (password && password !== confirmPassword) {
errors.confirmPassword = DefaultValidateErrors.confirmPasswordMatch;
}
tslint has flagged this as tsr-detect-possible-timing-attacks which sounds correct but how do I fix it.
If you are in node and version v6.6.0+, then you can use the crypto module's timingSafeEqual.
const crypto = require('crypto');
const isValid = crypto.timingSafeEqual(Buffer.from(password), Buffer.from(confirmPassword));
Node crypto docs
I think this is a false positive and you can just suppress the lint warning. The lint rule looks for any variable named password, but a timing attack is only relevant when data unknown to the client is involved, e.g., when checking a password specified by a client trying to log in against the saved correct password. It looks like this code is just validating a new password being set by an authenticated user.
That said, for avoiding timing attacks when they are relevant, a web search found me the rule documentation, which links to a post with a suggested solution to compare two passwords in constant time using bitwise operations. (You would think that functionality would be in a library somewhere. Maybe it is.)

Using a config file for JWT secret in Node.js

I am learning Node.js, and while implementing JWT I want to put a separate config.js file to set the secret to generate and verify tokens, but I am having trouble with this.
First I create the config file as follows:
// JWT config
module.exports.jwt_secret = 'mysecret';
Then I require it at the API endpoint as:
const jwt_secret = require('../../../../../config');
And finally, I try to use it as follows:
jwt.verify(token, (jwt_secret), function(err, decoded) { ... }
But it does not work, so I tried a console.log with the jwt_secret, and I get this:
{ jwt_secret: 'mysecret' }
I checked code and searched here at Stack Overflow but I do not see how to solve this. I know probably it is pretty obvious but as I said I am quite new at programming and I am learning.
Thank you in advance.
Taking a quick look at the node-jsonwebtoken api, verify seems to expect a string as the second argument. The way that you've set up your export and require means that your variable jwt_secret is the entire exports object from your config module, not the string. Try changing it to
jwt.verify(token, jwt_secret.jwt_secret, function(err, decoded) { ... }
and if that works, you may want to modify your require statement to something like
const config = require('some/path/config');
and then use config.jwt_secret as the argument. That's just style though, do what works for your project.

Categories