Setting a request header in NodeJS - node.js

I'm quite new to NodeJS. Lately, I've been trying to create a Login page with authentication using JWT and I've been running into the same error for a week now.
Here is my logic though:
user sign up and is been given an access token using JWT via
const token = jwt.sign({username:this.username, _id: this._id}, config.get('private keys));
req.headers.authorization = token;
While login in, I did this;
const token = req.headers.authorization;
if(!token) return res.send("Access denied");
...
But then, every time I try to login, I always get Access denied, I don't know if it should be req.headers.authorization or res.headers["authorization"], or if the problem is in the sign up page.

Can you tell us how you are sending the http requests?
Normally, when using postman, you should get a token with your default login route and then add the token in a new header with "Authorization" name and "Token " in value.

Related

Logout JWT with nestJS

I'm using JWT passaport to login module:
async validateUser(userEmail: string, userPassword: string) {
const user = await this.userService.findByEmail(userEmail);
if (user && user.password === userPassword) {
const { id, name, email } = user;
return { id: id, name, email };
}else {
throw new UnauthorizedException({
error: 'Incorrect username or password'
});
}
}
async login(user: any) {
const payload = { email: user.email, sub: user.id };
return {
access_token: this.jwtService.sign(payload),
};
}
This part is running.
My question is: how do the logout? I read about creating a blacklist and adding the token to it, but how do I get the user's access token?
Something you should know about token-based authentication is that it is stateless. This means that even the server does not keep track of which users are authenticated, like with session-based authentication. As such, you do not need to do anything on the server side to "log out" a user. You simply need to delete the t\JWT token on the client. If you make a request to the server app, without a valid JWT token, it will be treated as the user is not logged in.
Generally when a logout request would be sent the Authorization header should be present, so you can grab the token from there. Then you can save the token to the database's restrict list table.
When user click to "Log out" btn, you should sent a request which is attached Authorization header with bearer token. In the backend side, you need to extract header and push the token to the blacklist token (as your solution). Basically, you only need remove token in client side, it's so easy to do but in the worst case when the token was stolen by hacker, your token still valid. Using blacklist token is more secure but it can be lead to performance issue and scalable. What is the best solution? it's depend on you.
Read the Nestjs Execution context get the token from the request header and verify this token from JWT.
everything defines in the NESTJS link
//here we check the token from the header is valid or not expired
const tokenVarify = await this.jwtService.verify(token);
my idea is make whitelist every generate new token and remove it when user logout. so u need to check on guard also every user with token access its exist on whitelist or note
You must be refresh expire token to 1ms with:
https://webera.blog/how-to-implement-refresh-tokens-jwt-in-nestjs-b8093c5642a9
Actually there is a workaround for this, but not so straightforward!
The idea is to keep track of the tokens for logged out users (use some sort of black-list) and query provided token against that black-list.
To sum it up, you can follow these 4 steps:
Set a reasonable expiration time on tokens
Delete the stored token from client side upon log out
Have DB of no longer active tokens that still have some time to live
Query provided token against The Blacklist on every authorized request
For detailed explanations, you can check this post: medium
A guide in how to do the implementation is in this youtube video
Code with Vlad
, and there's as well the github source nestjs-jwts. I followed this video and implemented myself as well..

Laravel sanctum token after Authorization

I am using Laravel Sanctum in my project.
I have created the middleware to add the authorization header (Bearer token) for every API request. Auth user has token but it is hashed in the database. I want to send the token (which is authorized) for the next requests. How can I get the authenticated token value (like JWT token)?
You can get the plainTextToken only when it's first created. Once it's created, there is no way to get it again. It is returned in the token/create response body. Capture it and don't lose it, it will be the only way for that user to communicate/authenticate with your sanctum protected routes. Once it's created a hashed (non-decryptable) version is saved to the database. The plain text token that you save from the tokens/create method is hashed and compared to this to confirm the identity of the user. Unlike JWT, you won't get new iterations of the same token after creation.
See more here: https://laravel.com/docs/8.x/sanctum#issuing-api-tokens
you cab catch token from header like this
$token = null;
$headers = apache_request_headers();
if (isset($headers['Authorization'])) {
if (strpos($headers['Authorization'], 'Bearer') !== false) {
$token = str_replace('Bearer ', '', $headers['Authorization']);
}
}

Not able to handle Authorization using JWT

Im trying to create a protected route , once the user logs in user is issued a token and this token is checked when user tries to access a protected resource . Im able to generate the token and send it back as a response as the below code,
const token = jwt.sign({_id:found._id.toString()},process.env.KEY);
res.header('token', token );
res.render("dashboard");
So after a user is logged in , i go to the dashboard and i can see the response header where token is set as token .But when i try to navigate to the secret resource page the auth handler gets a request,but the request does not have a token in the header so im not able to verify it.
router.get('/secret',auth,function(req,res)
{
res.render('secret')
}
);
Trying to figure out how to set the token header correctly so it is issued and can verify it.
on client side, you should send token in header as authorization
after that, you can receive client's token on backend side using
req.get('Authorization')
and verify it using
jwt.verify

AquireTokenAsync with old access token ADAL

I am developing an app on Xamarin. I am trying to implement a single sign on across multiple apps. For this I authenticate the user first time with Azure AD using ADAL and user enters the credentials in the O365 page displayed by ADAL in the AcquireTokenAsync().
var authContext = new AuthenticationContext(ServiceConstants.AUTHORITY);
var authResult = await authContext.AcquireTokenAsync(resourceUri, ServiceConstants.CLIENTID, ServiceConstants.RETURNURI, param);
var apiAccessToken = authResult.AccessToken;
When successfully authenticated, I save the received token to a file which does persists even if the user uninstalls the app.
Now next time the user starts the app, I pass the saved token to the
AcquireTokenAsync() as UserAssertion
//Pass old accessToken
var userAssertion = new UserAssertion(accessToken);
var authResult = await authContext.AcquireTokenAsync(resourceUri, ServiceConstants.CLIENTID, userAssertion);
This works as expected and the user is authenticated without showing the O365 login screen.
Now I want this same behavior when the user uninstalls the app and reinstalls it. In my case, when the user uninstalls and reinstalls the app, I try to get a fresh token in the same way by adding the saved token as UserAssertion to the AquireTokenAsync(). However I get an error like so :-
Invalid JWT token. Token format not valid.
I cross checked the Token via Postman and it is a valid token.
EDIT
Any idea on how I can resolve this? Or a better way I can implement the same? Any help is highly appreciated.
If you have got the refresh_token, we can use this token to acquire the access_token silently directly via the RETS.
Here is a example for your reference:
POST /{tenant}/oauth2/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&refresh_token=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq...
&grant_type=refresh_token
&resource=https%3A%2F%2Fservice.contoso.com%2F
&client_secret=JqQX2PNo9bpM0uEihUPzyrh // NOTE: Only required for web apps
More detail please refer the link below.
Refreshing the access tokens

Nodejs Google Drive API

I am trying to understand how the authorization(particular the refresh tokens) working for nodejs Google Drive API.
Here it's the code from https://github.com/google/google-api-nodejs-client.
oauth2Client.credentials = {
access_token: 'ACCESS TOKEN HERE',
refresh_token: 'REFRESH TOKEN HERE'
};
client
.plus.people.get({ userId: 'me' })
.withAuthClient(oauth2Client)
.execute(callback);
General Question:
How does refresh tokens actually work together with access token?
Background:
As what I interpret is that each access token has a limited timespan (~1 hr). So when a user FIRST connect to my server (which the server provides mechanism for user authentication), the server receives limited-life access token and ONE-TIME refresh token. After 1 hour, the access token is expired.
Specific question:
Here comes to the key questions. After the expiration, my server stills send request to the Google Drive Api with the EXPIRED access token and refresh token (Server uses session to store those values). Will this still be able to access the content in Google Drive? What I am guessing is that the nodejs lib + google drive api is SMART enough to detect the access token is expired & refresh token is identified & api replace the expired access token with new access token blindly (like server does not need to do anything; just google drive api). Will the api response the server with a new Access Code?
I need to figure this out because I need to organize my code in Nodejs effectively.
Thanks!
Yes.
The Node.js API client will detect access token errors and automatically refresh the token.
You can see this in the source:
var hasAuthError = res.statusCode == 401 || res.statusCode == 403;
// if there is an auth error, refresh the token
// and make the request again
if (!opt_dontForceRefresh && hasAuthError && credentials.refresh_token) {
// refresh access token and re-request
that.refreshToken_(credentials.refresh_token, function(err, result) {
if (err) {
opt_callback && opt_callback(err, null, null);
} else {
var tokens = result;
tokens.refresh_token = credentials.refresh_token;
that.credentials = tokens;
that.request(opts, opt_callback, true);
}
});
}

Resources