#Nestjs authentication: Unknown authentication strategy "jwt"

172 messages · Page 1 of 1 (latest)

idle river
tidal birch
#

Where do you add the strategy to a providers array?

idle river
#

jwt.strategy.ts

#

this what u mean right?

tidal birch
#

No. I mean where is it added to a module's providers array

idle river
#

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 ?

tidal birch
#

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

idle river
#

like this?

tidal birch
#

Yeah, but you don't need the private here. Technically you don't need the readonly either

idle river
#

oh okey, what do i do now? because it still says jwtstrategy requires a secret or key

tidal birch
#

Do you have a JWT_SECRET_KEY in your .env file?

idle river
#

now i am confused if i should use the ' '

tidal birch
#

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 😆

idle river
#

what do you suggest i use?

tidal birch
#

I think the secret might need to be secretOrKey. Let me double check

idle river
#

but i also have a file constants.ts where i used this key is this the same key ?

tidal birch
#

And yeah, the property should be secretOrKey, not just secret

idle river
#

i read online something about constants that have data leaks

#

but i can use it like this tho

tidal birch
#

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

idle river
tidal birch
# idle river 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

idle river
#

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

tidal birch
#

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);
}
idle river
#

right here?

tidal birch
#

Yep

#

It's just a simple debug line between passport and Nest's handling of the invalid request

idle river
#

where should i see this appear? it looks like a log or something

tidal birch
#

It should show up in the server's logs

#

It's a console.log() statement of an object

idle river
#

its weird it doesn't show up

tidal birch
#

Did the server restart after the code change?

idle river
#

no, i will do this

#

nope still not happening

tidal birch
#

Is the route you're hitting using the JwtAuthGuard?

idle river
#

it should be

tidal birch
#

What endpoint are you hittin?

idle river
#

sorry i dont understand this question

tidal birch
#

You're making a request to your server at an endpoint. What endpoint is that? Is it in your GitHub repo?

idle river
#

oh no, i can show it here if you want

tidal birch
#

Please do

idle river
#
// 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?

tidal birch
#

I want to see the endpoint on the server that you're hitting

idle river
#

oh my database ?

#

or i dont understand

tidal birch
#

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

idle river
#

my whole nestjs code is on the git

tidal birch
#

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

idle river
#

yes

tidal birch
#

First things first, why do you need a JWT to log in?

#

Shouldn't you be logging in to get a JWT?

idle river
#

well that sounds right

tidal birch
#

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

idle river
#

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?

tidal birch
#

Yep

idle river
#

so just to have a confirm

#

i have to put them

#

here ?

tidal birch
#

If you want, you can do @UseGuards(JwtAuthGuard) at the controller class level rather than on each method

idle river
#

like this?

tidal birch
#

Yep

idle river
#

i see

tidal birch
#

Now the guard is bound to every route in the class

idle river
#

So bassicaly i removed it here
and when i log in it can use the jwt key on my other controllers

tidal birch
#

Your login, in theory, should return a JWT to use for the rest of your application, yes

idle river
#

else i cant acces the data thats what makes it a good middlewere
oh i am not done then?

tidal birch
#

oh i am not done then?
What do you mean?

idle river
#

wait i would like you to confirm my last thing to return the key

tidal birch
#

From the code you have online, yes, your login does return a JWT

idle river
#

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?
tidal birch
#

I would probably throw an exception (HTTP 401/403) instead of returning a positive response (HTTP 200/201)

idle river
#

huh what ?

tidal birch
#

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

idle river
#

is it the readonly

tidal birch
#

readonly doesn't actually impact runtime. It's jsut a way to say that a class value is const during type checking

idle river
#

UnauthorizedException is with try catch right

#

i have this right now

idle river
#

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

tidal birch
#

Error: no auth token

#

You aren't sending the header you are expected to

#

Which looks like your login route is still being protected

idle river
#

my route, thats weird because i am not using guards with my login anymore

tidal birch
#

According to the error, it's still guarded'

#

Do you have APP_GUARD used in any providers? Or useGlobalGuards() in the main?

idle river
#

no i do not

tidal birch
#

Is your current code up on GitHub?

idle river
#

you want my nestjs or angular to?

idle river
#

this was before update

tidal birch
#

Did you just recently push?

idle river
#

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

tidal birch
#

And you're certain this is the server code you're running?

idle river
#

yes 100%

tidal birch
#

Can you stop your server and restart just tp be certain?

idle river
#

i left my purchases and sales file out but it is only showing a list of items

tidal birch
#

I don't see a reason for this to trigger the guard

idle river
#

i restarted it and it is the right api

tidal birch
#

Still hitting the guard?>

#

The code was also recompiled, yeah?

idle river
#

not hitting the guard but not login in either,
yes i recompiled both

tidal birch
#

Well that's a step in the right direction then

idle river
#

true

#

cant post angular code here right?

tidal birch
#

You can if you want

#

Not sure how that would help though

idle river
#

maybe you know what im doing wrong it has to do with the same login problem i am having

tidal birch
#

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

idle river
#
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
tidal birch
#

Does it work when using postman or curl (or similar)?

idle river
#

but i feel like that has something to do with hash

tidal birch
#

It might. Have you verified where the error is trhown from? Checked the stack traces and all that?

idle river
#

its from my users.service

tidal birch
#

You throw it from multiple possible places, right? You really should trace those errors better

idle river
#

i dont know how this works

tidal birch
#

How what works?

idle river
#

i ment i am trying to figure out how i better do this wait

#

so bassicaly the credentials are correct, but something goes wrong

tidal birch
#

Then check all along the flow where that could be happening. Use log statements or a debugger to determine the issue

idle river
#

i did try to log some things in nestjs but i do not see anything

tidal birch
#

Using console.log()? It should show up in the terminal

idle river
#

no i am trying that

tidal birch
#

Are you checking in the valdiateUser as well?

idle river
#

Yes but it aint popping in the logs

tidal birch
#

Then you aren't reaching those points. Or you didn't rebuild the server

idle river
tidal birch
#

Wait, those are the browser logs

#

You should be looking in the terminal where you're running your server

idle river
#

console.log is browser log right?

#

oh in terminal neither

tidal birch
idle river
#

nope in terminal neither

tidal birch
#

Okay, then I'll say it again: the server wasn't rebuilt, or you aren't reaching that point in the code

idle river
#

i did rebuild

#

and if i use postman i get the error i put in so i should be getting on that point tho

tidal birch
#

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

idle river
#

ah ye thats right

#

oh i see

#

now i get loggs

idle river
#

i dont know why it is undefined

#

it put value in it

tidal birch
#

Some method in users service. I'll have to check when I'm back at my laptop

idle river
#

oh okey, thanks for your time
can u tag me when u check

idle river
#

don't i need too ? because i have to get the dto

tidal birch
#

req.user isn't populated. That normally gets populated by passport, which shouldn't be running on this route

#

You should be using req.body instead

idle river
#

aight i try test it

#

still problem

tidal birch
#

.boy not .Body

#

Keys are case sensitive

idle river
#

oh

#

yes

#

it works