我使用 Angular 作为前端和 Nestjs 作为后端开发了一个全栈应用程序。该项目使用 NX 组织在一个单一存储库中。该项目在我的本地机器上运行良好,包括身份验证(来自 Nestjs 的 Passport 库)。
所以我决定对应用程序进行 docker 化,但是当应用程序在 docker 容器中运行时,来自 Nestjs 后端的受保护路由无法访问,尽管使用了从运行在码头集装箱。
我将项目从 bcrypt 迁移到 bcryptjs,因为在构建 docker 容器时出现错误。最让我困惑的是,在我的本地机器上一切正常,但在 docker 容器中,尽管使用了我从后端获得的 JWT 令牌,但受保护的路由仍无法访问。
Dockerfile
FROM node:14
ENV PORT=3333
WORKDIR /app
COPY ["package.json", "package-lock.json*", "npm-shrinkwrap.json*","nx.json", "./"]
RUN npm install
COPY ./apps .
EXPOSE 3333
CMD npm start
码头工人-compose.yml
version: '3.4'
services:
myapp:
image: myapp
build:
context: .
dockerfile: ./Dockerfile
volumes:
- .:/app
depends_on:
- postgres
environment:
API_PORT: 3333
JWT_SECRET: verystrongsecret
JWT_EXPIRES_IN: 3600
DB_TYPE: postgres
DB_PORT: 5432
DB_HOST: postgres
DB_USERNAME: user
DB_PASSWORD: password
DB_NAME: db
NODE_ENV: development
TYPEORM_SYNC: 'true'
ports:
- 3333:3333
postgres:
image: postgres:10.4
ports:
- 5432:5432
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: db
如何解决身份验证问题?什么可能导致 docker 出现这种奇怪的行为?
Jwt策略:
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(
@InjectRepository(UserRepository) private userRepository: UserRepository
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: process.env.JWT_SECRET || config.get('jwt.secret'),
});
}
async validate(payload: JwtPayload): Promise<User> {
const { email } = payload;
const user = await this.userRepository.findOne({ email });
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
为了保护我正在使用的路线:护照库的@UseGuards(AuthGuard())
位置AuthGuard
。
授权模块:
@Module({
imports: [
PassportModule.register({ defaultStrategy: 'jwt' }),
JwtModule.register({
secret: process.env.JWT_SECRET || jwtConfig.secret,
signOptions: {
expiresIn: process.env.JWT_EXPIRES_IN || jwtConfig.expiresIn,
},
}),
TypeOrmModule.forFeature([UserRepository]),
],
controllers: [AuthController],
providers: [AuthService, JwtStrategy],
exports: [AuthService, JwtStrategy, PassportModule],
})
export class AuthModule {}