I am trying to use my login function but i have a problem i don't quite get i have a feeling it is in my api
I will put my github link and the code in this chat i think it has something to do with my jwt-auth.guard-module.ts
https://github.com/SkyFerian/angular-error/tree/main/src
cant figure it out
#Nestjs authentication: Unknown authentication strategy "jwt"
172 messages · Page 1 of 1 (latest)
Where do you add the strategy to a providers array?
No. I mean where is it added to a module's providers array
I see i did not provide it anywhere, but if i do it tells me jwtstrategy requires a secret or key but i do have a secret ?
process.env is probably not populated yet, and you should use ConfigService instead of process.env so that you can ensure it is populated as expected
like this?
Yeah, but you don't need the private here. Technically you don't need the readonly either
oh okey, what do i do now? because it still says jwtstrategy requires a secret or key
Do you have a JWT_SECRET_KEY in your .env file?
As you have the $ there, using the '' is a good idea to ensure that the shell env doesn't end up misinterpreting the value.
Interesting to use a bcrypt hashed value for the key, but I suppose it works 😆
what do you suggest i use?
I think the secret might need to be secretOrKey. Let me double check
but i also have a file constants.ts where i used this key is this the same key ?
So why aren't you using the constants file then?
And yeah, the property should be secretOrKey, not just secret
i read online something about constants that have data leaks
but i can use it like this tho
Generally, I prefer to use a constants file for non-secret values that need to be re-used. Prefixes, common time lengths, messages etc. I prefer to keep secrets through my configuration service integration
what do you suggest i use there?
Oh, the bcrypt hashed value is fine, it's just not something I normally see. I can just recognize that it's a bcrypt value because of the format, but have absolutely no clue what the original value was, and seeing that it's a pretty random string it's gonna be a generally good secret
oh okey, now i have added the constant, i am gonna test it
I feel like it should work but it doesn't, when i try to use the login it gives me a 401 unauthorized
That would lead me to believe the request is sent incorrectly or the JWT is expired or invalid for some other reason
Add this to the guard that extends AuthGuard('jwt') and you can get more information about what's happening in the request
handleRequest(...args: Parameters<InstanceType<ReturnType<typeof AuthGuard>>['handleRequest']>) {
console.log(args);
return super.handleRequest(...args);
}
right here?
Yep
It's just a simple debug line between passport and Nest's handling of the invalid request
where should i see this appear? it looks like a log or something
its weird it doesn't show up
Did the server restart after the code change?
Is the route you're hitting using the JwtAuthGuard?
it should be
What endpoint are you hittin?
sorry i dont understand this question
You're making a request to your server at an endpoint. What endpoint is that? Is it in your GitHub repo?
oh no, i can show it here if you want
Please do
// after pressing the login -> goes to authservice login()
onSubmit() {
this.submitted = true;
this.loading = true;
this.mymodel.username = this.loginForm.get('username')?.value;
this.mymodel.password = this.loginForm.get('password')?.value;
console.log(this.mymodel);
this.authService.login(this.mymodel).subscribe({
next: () => {
console.log('werkt');
},
error: () => ((this.loading = false), console.log('error')),
});
}```
```ts
//service
private apiUrl = 'http://localhost:3000/api/gebruikers';
constructor(private http: HttpClient) {}
login(loginUser: Loginmodel): Observable<any> {
return this.http
.post<any>(`${this.apiUrl}/login`, loginUser, this.getHttpOptions())
.pipe(
map((response) => {
localStorage.setItem('token', response.access_token);
return true;
}),
catchError((error: HttpErrorResponse) => {
if (error.status === 409) {
const errorMessage =
'There is a problem with the token, if this keeps happening contact the server admin';
throw new Error(errorMessage);
}
throw new Error('Something went wrong');
})
);
}
this what u wanted to see right?
I want to see the endpoint on the server that you're hitting
The code you are showing looks to be the client (website) code that calls to your server. I want to see the NestJS code for the endpoint (the controller, the route handler, what decorators are used, etc.)
my whole nestjs code is on the git
Okay. So this is what you are trying to hit?
import { Request, Controller, Post, UseGuards, Body } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { AuthService } from '../auth/auth.service';
import { UsersService } from './users.service';
@Controller('gebruikers')
export class UsersController {
constructor(
private readonly authService: AuthService,
private readonly usersService: UsersService
) {}
@Post('login')
@UseGuards(AuthGuard('jwt'))
async login(@Request() req) {
return this.usersService.login(req.user);
}
@Post('register')
async register(
@Body() registerData: { username: string; email: string; password: string }
): Promise<{ access_token: string }> {
const { username, email, password } = registerData;
const user = await this.usersService.register(username, email, password);
const token = await this.authService.generateJwtToken(user);
return { access_token: token.access_token };
}
}
This @Post('login') method
yes
First things first, why do you need a JWT to log in?
Shouldn't you be logging in to get a JWT?
well that sounds right
Secondly, you're using AuthGuard('jwt'), not the JwtAuthGuard so you won't get any of the changes you made in JwtAuthGuard to activate. They're different guards
I see i didn't know that, so bassiacly i do not need to use this guards here, i need to use them in the controllers from my other things where i am going for data?
Yep
If you want, you can do @UseGuards(JwtAuthGuard) at the controller class level rather than on each method
like this?
Yep
i see
Now the guard is bound to every route in the class
So bassicaly i removed it here
and when i log in it can use the jwt key on my other controllers
Your login, in theory, should return a JWT to use for the rest of your application, yes
else i cant acces the data thats what makes it a good middlewere
oh i am not done then?
oh i am not done then?
What do you mean?
wait i would like you to confirm my last thing to return the key
From the code you have online, yes, your login does return a JWT
ooh i see
i understand
I am still receiving an error but not in the same category
it is when i am login in
const user = await this.userService.validateUser(loginDto.username, loginDto.password);
if (!user) {
return { message: 'Invalid credentials' };
}```
should i use something like this?
I would probably throw an exception (HTTP 401/403) instead of returning a positive response (HTTP 200/201)
huh what ?
Instead of return { message: 'Invalid credentials' } I would throw new UnauthorizedException('Invalid credentials') or similar
As for why you're getting that error, check the loginDto
is it the readonly
readonly doesn't actually impact runtime. It's jsut a way to say that a class value is const during type checking
Sorry to desturb you Jmcdo, but when i login it does not work, i get error no auth token
Can u tell me what is happening? if u know
Error: no auth token
You aren't sending the header you are expected to
Which looks like your login route is still being protected
my route, thats weird because i am not using guards with my login anymore
According to the error, it's still guarded'
Do you have APP_GUARD used in any providers? Or useGlobalGuards() in the main?
no i do not
Is your current code up on GitHub?
you want my nestjs or angular to?
this was before update
Did you just recently push?
i use other file to upload it to git cus else i upload a whole project
i will push it in a sec
now i pushed
And you're certain this is the server code you're running?
yes 100%
Can you stop your server and restart just tp be certain?
i left my purchases and sales file out but it is only showing a list of items
I don't see a reason for this to trigger the guard
i restarted it and it is the right api
not hitting the guard but not login in either,
yes i recompiled both
Well that's a step in the right direction then
maybe you know what im doing wrong it has to do with the same login problem i am having
Well, first, does it work with postman or curl?
If the endpoint works from those, then it's an issue with the client calling the server. If not, it's an issue on the server that should be addressed
onSubmit() {
this.submitted = true;
this.loading = true;
this.username = this.loginForm.get('username')?.value;
this.password = this.loginForm.get('password')?.value;
console.log(this.mymodel);
this.authService.login(this.username, this.password).subscribe({
next: () => {
console.log('werkt');
},
error: () => ((this.loading = false), console.log('error')),
});
}```
```ts
private apiUrl = 'http://localhost:3000/api/gebruikers';
constructor(private http: HttpClient) {}
login(email: string, password: string): Observable<any> {
return this.http.post<any>('/api/login', { email, password }).pipe(
map((response) => {
localStorage.setItem('token', response.access_token);
return true;
}),
catchError((error: HttpErrorResponse) => {
if (error.status === 409) {
const errorMessage =
'There is a problem with the token, if this keeps happening contact the server admin';
throw new Error(errorMessage);
}
throw new Error('Something went wrong');
})
);
}```
ye iknow but it seem like u know a lot about this,
so i feel like u can guide me
Does it work when using postman or curl (or similar)?
but i feel like that has something to do with hash
It might. Have you verified where the error is trhown from? Checked the stack traces and all that?
its from my users.service
You throw it from multiple possible places, right? You really should trace those errors better
i dont know how this works
How what works?
i ment i am trying to figure out how i better do this wait
so bassicaly the credentials are correct, but something goes wrong
Then check all along the flow where that could be happening. Use log statements or a debugger to determine the issue
i did try to log some things in nestjs but i do not see anything
Using console.log()? It should show up in the terminal
Are you checking in the valdiateUser as well?
Yes but it aint popping in the logs
Then you aren't reaching those points. Or you didn't rebuild the server
Wait, those are the browser logs
You should be looking in the terminal where you're running your server
console.log is for JavaScript
nope in terminal neither
Okay, then I'll say it again: the server wasn't rebuilt, or you aren't reaching that point in the code
i did rebuild
and if i use postman i get the error i put in so i should be getting on that point tho
Not f you throw you shouldn't
When you throw an error you skip all code after it until thecatch statement, right?
That's how error management works
Some method in users service. I'll have to check when I'm back at my laptop
oh okey, thanks for your time
can u tag me when u check
https://github.com/SkyFerian/angular-error/blob/main/src/app/users/users.controller.ts#L14 why are you using req.user here?
don't i need too ? because i have to get the dto