Laravel sanctum token after Authorization - laravel-7

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']);
}
}

Related

Is a good idea pass decoded jwt data via express req parameters?

In my NodeJs application im using jwt to manage the user session, inside a jwt token i store user_role and user_id. This is my route:
routes.post('/manga/post', Authorize("Scan"), MangaMiddleware.valid_manga_store, MangaController.store);
In the middleware Authorize("Scan") I verify the jwt token with "jwt.verify", if its valid i going to check if there is a active user with the token id and if his permission allow him to access this route, if so i use next()
In MangaController.store i going to save a new manga, and i need to save in the document the user_id who made the request.
That's my point, i already decoded the token in Authorize middleware but the decoded data do not persist out of the middleware. To access the user_id from MangaController i have to verify the token again.
I think i should avoid verify the same token twice, so in the middleware Authorize after verifying i was saving the user_id (encrypted) inside req.auth and after use it in the controller, i was setting req.auth = null. This way the user_id is stored in req.auth for a short period of time.
req.auth = user_id //after encrypting
My friend told me this is a bad idea storing decoded data inside req parameters, but i don't think it is this bad.
In a nutshell. Do i need to verify the token twice? Is there another way to retrieve this data? It is that bad storing decoded data in req parameters? I do appreciate your time and help.
Verifying and decoding JWT are two different things. When you verify, it's checking for its integrity, ie making sure it has not been tampered with, while decoding JWT means converting from base64 to readable format (UTF-8?). So it doesn't have to be verified twice.
Assuming you sent your token in headers as "token":"base64encodedJwt", then after successful verification, whenever you need user_id, you can then simply decode the JWT. Use some JWT decode library.
let token = req.get('token') || req.headers['token'];
let payload = decodeJWT(token);
let userId = payload.user_id;
If you are not storing it in req object, then you will have to decode it everytime you need it. So req.auth = userId should be fine.

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..

Setting a request header in NodeJS

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.

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

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