#cookie set on one endpoint doesn't show up on another endpoint

1 messages · Page 1 of 1 (latest)

solemn panther
#

profile.controller.ts

import { Body, Controller, Param, Post, UseGuards } from '@nestjs/common';
import { Profile } from '@/profile/profile.service';
import { JwtAuthGuard } from '@/auth/guards/jwt.guard';

@Controller('api')
export class ProfileController {
    constructor(private profile: Profile) {
    }

    @UseGuards(JwtAuthGuard)
    @Post('user/:userId/profile')
    async postProfile(@Param() params, @Body() body) {
        await this.profile.add(params.userId, body);
    }
}

auth.controller.ts

import { Controller, Get, Req, Res, UseGuards } from '@nestjs/common';
import { OAuthGuard } from '@/auth/guards/oauth.guard';
import { Response } from 'express';
import { DbService } from '@/db/db.service';
import { eq } from 'drizzle-orm';
import { users } from '@/db/schema';
import { JwtAuthService } from '@/auth/jwt-auth.service';

@Controller('auth')
export class AuthController {
    constructor(private readonly dbService: DbService, private jwtAuth: JwtAuthService) {
    }

    @Get('login')
    @UseGuards(OAuthGuard)
    async login() {
        // This route will redirect the user to the OAuth provider
        // The guard will handle the redirection
    }

    @Get('callback')
    @UseGuards(OAuthGuard)
    async callback(@Req() req, @Res() res: Response) {
        // Access the user information from the request
        const user = await this.dbService.database.query.users.findFirst({ where: eq(users.providerId, req.user.id) });
        const { accessToken } = this.jwtAuth.login(user.id, user.username);

        res.cookie('jwt', accessToken, {
            httpOnly: true,
        });

        if (user.isActive) {
            res.redirect(`${process.env.FRONTEND_URL}/login-success?id=${user.id}`);
        } else {
            res.redirect(`${process.env.FRONTEND_URL}/profile?id=${user.id}`);
        }
    }
}
#

jwt.validator.ts

import { Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';

export type JwtPayload = { sub: number; username: string };

@Injectable()
export class JwtValidator extends PassportStrategy(Strategy) {
    constructor(configService: ConfigService) {
        const extractJwtFromCookie = (req) => {
            let token = null;

            if (req && req.cookies) {
                token = req.cookies['jwt'];
            }
            return token;
        };

        super({
            jwtFromRequest: extractJwtFromCookie,
            ignoreExpiration: false,
            secretOrKey: configService.get<string>('JWT_SECRET'),
        });
    }

    async validate(payload: JwtPayload) {
        return { id: payload.sub, username: payload.username };
    }
}

jwt-auth.service.ts

import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { JwtPayload } from '@/auth/validators/jwt.validator';

@Injectable()
export class JwtAuthService {
    constructor(private jwtService: JwtService) {
    }

    login(id, username) {
        const payload: JwtPayload = { username, sub: id };
        return {
            accessToken: this.jwtService.sign(payload),
        };
    }
}
#

auth.module.ts

import { Module } from '@nestjs/common';
import { OAuthValidator } from '@/auth/validators/oauth.validator';
import { AuthController } from '@/auth/auth.controller';
import { PassportModule } from '@nestjs/passport';
import { OAuthGuard } from '@/auth/guards/oauth.guard';
import { JwtModule } from '@nestjs/jwt';
import { ConfigService } from '@nestjs/config';
import { JwtAuthGuard } from '@/auth/guards/jwt.guard';
import { JwtAuthService } from '@/auth/jwt-auth.service';
import { JwtValidator } from '@/auth/validators/jwt.validator';

@Module({
    imports: [
        PassportModule.register({ defaultStrategy: 'jwt' }),
        JwtModule.registerAsync({
            useFactory: async (configService: ConfigService) => {
                return {
                    secret: configService.get<string>('JWT_SECRET'),
                    signOptions: {
                        expiresIn: configService.get<string>('JWT_EXPIRES_IN'),
                    },
                };
            },
            inject: [ConfigService],
        }),
    ],
    controllers: [
        AuthController
    ],
    providers: [
        OAuthValidator,
        OAuthGuard,
        JwtAuthGuard,
        JwtAuthService,
        JwtValidator,
    ],
    exports: [JwtModule, JwtAuthGuard, JwtAuthService],
})
export class AuthModule {
}