undefined when accessing an object in NestJS

huangapple go评论75阅读模式
英文:

undefined when accessing an object in NestJS

问题

I am building a NestJS API with JWT Token and Refresh Token.

When I am trying to get a new access token using the refresh token, I am running into a strange issue.

I noticed that when I am generating a new access token using the refreshToken function, it contains an empty payload. When I investigated the issue, I found out that when I write console.log(user), I can see the values of the user object in the console. However, when I start accessing the properties of the user object to populate the payload, they are all undefined.

Here code for the refresh token strategy:

  1. import { Injectable } from '@nestjs/common';
  2. import { ConfigService } from '@nestjs/config';
  3. import { PassportStrategy } from '@nestjs/passport';
  4. import { ExtractJwt, Strategy } from 'passport-jwt';
  5. @Injectable()
  6. export class RefreshJwtStrategy extends PassportStrategy(
  7. Strategy,
  8. 'jwt-refresh',
  9. ) {
  10. constructor(private readonly configService: ConfigService) {
  11. super({
  12. jwtFromRequest: ExtractJwt.fromBodyField('refresh'),
  13. ignoreExpiration: false,
  14. secretOrKey: configService.get<string>('jwt.refreshSecret'),
  15. });
  16. }
  17. async validate(payload: any) {
  18. return { user: payload.sub, userId: payload.userId };
  19. }
  20. }

Here is the code in the controller:

  1. @UseGuards(RefreshJwtGuard)
  2. @Post('/refresh')
  3. async refreshToken(@Request() req) {
  4. return await this.authService.refreshToken(req.user);
  5. }

Here is the code for the refreshToken:

  1. async refreshToken(user: User) {
  2. console.log(user); // It is working fine and I can see the object and its values
  3. const payload = {
  4. userId: user.id, // undefined
  5. sub: {
  6. id: user.id, // undefined
  7. username: user.username, // undefined
  8. email: user.email, // undefined
  9. },
  10. };
  11. console.log(payload); // the payload is showing as {}
  12. return {
  13. accessToken: this.jwtService.sign(payload),
  14. };
  15. }

This is what I am getting from logging the user:

  1. {
  2. user: {
  3. id: '8c5370bd-3b5c-404c-8362-fdb6efb84d75',
  4. username: 'owner1.1',
  5. email: 'owner1.1@gmail.com'
  6. },
  7. userId: '8c5370bd-3b5c-404c-8362-fdb6efb84d75'
  8. }

This is what I am getting when I am logging the Payload after attempting to get the values from the user:

  1. {
  2. userId: undefined,
  3. sub: { id: undefined, username: undefined, email: undefined }
  4. }

Any idea how to solve this? What is the issue?

英文:

I am building a NestJS API with JWT Token and Refresh Token.

When I am trying to get a new access token using the refresh token, I am running into a strange issue.

I noticed that when I am generating a new access token using the refreshToken function, it contains an empty payload. When I investigated the issue, I found out that when I write consol.log(user), I can see the values of the user object in the concol. However, when I start accessing the properties of the user object to populate the payload, they are all undefined.

Here code for the refresh token strategy:

  1. import { Injectable } from &#39;@nestjs/common&#39;;
  2. import { ConfigService } from &#39;@nestjs/config&#39;;
  3. import { PassportStrategy } from &#39;@nestjs/passport&#39;;
  4. import { ExtractJwt, Strategy } from &#39;passport-jwt&#39;;
  5. @Injectable()
  6. export class RefreshJwtStrategy extends PassportStrategy(
  7. Strategy,
  8. &#39;jwt-refresh&#39;,
  9. ) {
  10. constructor(private readonly configService: ConfigService) {
  11. super({
  12. jwtFromRequest: ExtractJwt.fromBodyField(&#39;refresh&#39;),
  13. ignoreExpiration: false,
  14. secretOrKey: configService.get&lt;string&gt;(&#39;jwt.refreshSecret&#39;),
  15. });
  16. }
  17. async validate(payload: any) {
  18. return { user: payload.sub, userId: payload.userId };
  19. }
  20. }

Here is the code in the controller:

  1. @UseGuards(RefreshJwtGuard)
  2. @Post(&#39;/refresh&#39;)
  3. async refreshToken(@Request() req) {
  4. return await this.authService.refreshToken(req.user);
  5. }

Here is the code for the refreshToken:

  1. async refreshToken(user: User) {
  2. console.log(user); //It is working fine and I can see the object and it&#39;s values
  3. const payload = {
  4. userId: user.id, //undefined
  5. sub: {
  6. id: user.id, //undefined
  7. username: user.username, //undefined
  8. email: user.email, //undefined
  9. },
  10. };
  11. console.log(payload); //the payload is showing as {}
  12. return {
  13. accessToken: this.jwtService.sign(payload),
  14. };
  15. }

This is what I am getting from logging the user:

  1. {
  2. user: {
  3. id: &#39;8c5370bd-3b5c-404c-8362-fdb6efb84d75&#39;,
  4. username: &#39;owner1.1&#39;,
  5. email: &#39;owner1.1@gmail.com&#39;
  6. },
  7. userId: &#39;8c5370bd-3b5c-404c-8362-fdb6efb84d75&#39;
  8. }

This is what I am getting when I am logging the Payload after attempting to get the values from the user:

  1. {
  2. userId: undefined,
  3. sub: { id: undefined, username: undefined, email: undefined }
  4. }

Any idea how to solve this? what is the issue?

答案1

得分: 2

你的 user 对象是一个具有名为 user 的属性的对象,它是另一个包含用户信息的对象,因为你在 validate 函数中返回它:

  1. return { user: payload.sub, userId: payload.userId }; // 这是你的 "user" 对象

因此,你需要从 user.user 而不是 user 中获取你想要的内容:

  1. const payload = {
  2. userId: user.user.id,
  3. sub: {
  4. id: user.user.id,
  5. username: user.user.username,
  6. email: user.user.email,
  7. },
  8. };

你也可以更新你的 validate 函数并保持代码不变:

  1. async validate(payload: any) {
  2. return payload.sub
  3. }
英文:

Your user object is an object with a property called user, it is another object that contain the user informations because you are returning this with the validate function:

  1. return { user: payload.sub, userId: payload.userId }; // this is your &quot;user&quot; object

Therefore you have to get what you want from user.user instead of user

  1. const payload = {
  2. userId: user.user.id,
  3. sub: {
  4. id: user.user.id,
  5. username: user.user.username,
  6. email: user.user.email,
  7. },
  8. };

You can also update your validate function and keep your code as it is:

  1. async validate(payload: any) {
  2. return payload.sub
  3. }

huangapple
  • 本文由 发表于 2023年6月6日 03:14:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76409392.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定