ferrerojosh / nest-keycloak-connect

keycloak-nodejs-connect module for Nest
MIT License
318 stars 123 forks source link

`Nest can't resolve dependencies of the AuthGuard` error message when trying to start the app #153

Closed kasir-barati closed 11 months ago

kasir-barati commented 1 year ago

I have a monorepo + pnpm and my NestJS app won't run since I have this error:

[Nest] 33726  - 04/29/2023, 6:10:24 PM   ERROR [ExceptionHandler] Nest can't resolve dependencies of the AuthGuard (?, KEYCLOAK_CONNECT_OPTIONS, KEYCLOAK_LOGGER, KeycloakMultiTenantService, Reflector). Please make sure that the argument KEYCLOAK_INSTANCE at index [0] is available in the ProfileModule context.

Potential solutions:
- Is ProfileModule a valid NestJS module?
- If KEYCLOAK_INSTANCE is a provider, is it part of the current ProfileModule?
- If KEYCLOAK_INSTANCE is exported from a separate @Module, is that module imported within ProfileModule?
  @Module({
    imports: [ /* the Module containing KEYCLOAK_INSTANCE */ ]
  })

Error: Nest can't resolve dependencies of the AuthGuard (?, KEYCLOAK_CONNECT_OPTIONS, KEYCLOAK_LOGGER, KeycloakMultiTenantService, Reflector). Please make sure that the argument KEYCLOAK_INSTANCE at index [0] is available in the ProfileModule context.

Potential solutions:
- Is ProfileModule a valid NestJS module?
- If KEYCLOAK_INSTANCE is a provider, is it part of the current ProfileModule?
- If KEYCLOAK_INSTANCE is exported from a separate @Module, is that module imported within ProfileModule?
  @Module({
    imports: [ /* the Module containing KEYCLOAK_INSTANCE */ ]
  })

    at Injector.lookupComponentInParentModules (/home/kasir/projects/you-say/node_modules/.pnpm/@nestjs+core@9.4.0_s52inwjga72fw7w7ilq4rk5hru/node_modules/@nestjs/core/injector/injector.js:247:19)
    at Injector.resolveComponentInstance (/home/kasir/projects/you-say/node_modules/.pnpm/@nestjs+core@9.4.0_s52inwjga72fw7w7ilq4rk5hru/node_modules/@nestjs/core/injector/injector.js:200:33)
    at resolveParam (/home/kasir/projects/you-say/node_modules/.pnpm/@nestjs+core@9.4.0_s52inwjga72fw7w7ilq4rk5hru/node_modules/@nestjs/core/injector/injector.js:120:38)
    at async Promise.all (index 0)
    at Injector.resolveConstructorParams (/home/kasir/projects/you-say/node_modules/.pnpm/@nestjs+core@9.4.0_s52inwjga72fw7w7ilq4rk5hru/node_modules/@nestjs/core/injector/injector.js:135:27)
    at Injector.loadInstance (/home/kasir/projects/you-say/node_modules/.pnpm/@nestjs+core@9.4.0_s52inwjga72fw7w7ilq4rk5hru/node_modules/@nestjs/core/injector/injector.js:61:13)
    at Injector.loadInjectable (/home/kasir/projects/you-say/node_modules/.pnpm/@nestjs+core@9.4.0_s52inwjga72fw7w7ilq4rk5hru/node_modules/@nestjs/core/injector/injector.js:84:9)
    at /home/kasir/projects/you-say/node_modules/.pnpm/@nestjs+core@9.4.0_s52inwjga72fw7w7ilq4rk5hru/node_modules/@nestjs/core/injector/instance-loader.js:80:13
    at async Promise.all (index 0)
    at InstanceLoader.createInstancesOfInjectables (/home/kasir/projects/you-say/node_modules/.pnpm/@nestjs+core@9.4.0_s52inwjga72fw7w7ilq4rk5hru/node_modules/@nestjs/core/injector/instance-loader.js:79:9)

Any idea?

Here is my repo, but besides using pnpm and monorepo I cannot see much of difference with the example app: https://github.com/kasir-barati/you-say

ferrerojosh commented 1 year ago

I think this is because you're scoping the guards into your controllers while you are using the keycloak module at the app level.

kasir-barati commented 1 year ago

I think this is because you're scoping the guards into your controllers while you are using the keycloak module at the app level.

I just wanna make sure that I understood it correctly, So you are implying that I need to reuse the same code in every module because I do not wanna have global guards?

Or let me ask it in another way, how can I have scoped guards and not global ones but still define the keycloak module once?

ferrerojosh commented 1 year ago

You need to register it in a separate module that is global. See: https://docs.nestjs.com/modules#global-modules

kasir-barati commented 1 year ago

@ferrerojosh Thanks buddy but no luck. Here is my latest commit and changes I did: https://github.com/kasir-barati/you-say/commit/ca8bda0db84b7c2a0450d3724bdf0e8d7a395646

I still get the same error message. What else I am doing wrong. I am sure I am missing something. Can you please tell how can I get the example up and running? I just

  1. cloned the repo
  2. removed everything except example
  3. pnpm i --frozen-lockfile
  4. Create a docker-compose.yml file
    version: '3'
    services:
      postgres:
        image: bitnami/postgresql:15.2.0-debian-11-r13
        restart: always
        environment:
          POSTGRESQL_USERNAME: ${POSTGRESQL_USERNAME}
          POSTGRESQL_PASSWORD: ${POSTGRESQL_PASSWORD}
          POSTGRESQL_DATABASE: ${POSTGRESQL_DATABASE}
        volumes:
          - keycloak_db_volume:/bitnami/postgresql
      keycloak:
        image: bitnami/keycloak:21.0.2-debian-11-r0
        restart: always
        depends_on:
          - postgres
        ports:
          - 8080:8080
          # - 8443:8443 HTTPS port
        environment:
          KEYCLOAK_CREATE_ADMIN_USER: true
          KEYCLOAK_ADMIN_USER: ${KEYCLOAK_ADMIN_USER}
          KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD}
          KEYCLOAK_DATABASE_HOST: postgres
          KEYCLOAK_DATABASE_PORT: 5432
          KEYCLOAK_DATABASE_NAME: ${POSTGRESQL_DATABASE}
          KEYCLOAK_DATABASE_USER: ${POSTGRESQL_USERNAME}
          KEYCLOAK_DATABASE_PASSWORD: ${POSTGRESQL_PASSWORD}
          KEYCLOAK_DATABASE_SCHEMA: public
          KEYCLOAK_ENABLE_STATISTICS: true
          KEYCLOAK_DATABASE_VENDOR: postgresql
          # https://www.keycloak.org/server/features
          KEYCLOAK_EXTRA_ARGS: --features=declarative-user-profile -Dkeycloak.import=/tmp/nest-example.json
          # KEYCLOAK_PRODUCTION: true In prod env and configure TLS pls
        volumes:
          - ./nest-example.json:/tmp/nest-example.json:ro
          - keycloak_volume:/tmp
          - ./packages/keycloakify/build_keycloak/src/main/resources/theme/you-say-keycloakify-theme:/opt/bitnami/keycloak/themes/you-say-keycloakify-theme:rw
    volumes:
      keycloak_volume:
      keycloak_db_volume:
  5. Create .env file:
    # Keycloak's envs 
    KEYCLOAK_ADMIN_USER=admin
    KEYCLOAK_ADMIN_PASSWORD=admin
    KEYCLOAK_AUTHORIZATION_SERVER_URL=http://localhost:8080
    KEYCLOAK_CLIENT_ID=you-say-backend
    KEYCLOAK_SECRET=secret
    KEYCLOAK_REALM=you-say-realm
    # Keycloak db's envs
    POSTGRESQL_DATABASE=keycloak
    POSTGRESQL_USERNAME=postgres
    POSTGRESQL_PASSWORD=admin

But now I am stuck because now my container won't run, I also tried to remove that ./nest-example.json:/tmp/nest-example.json:ro and -Dkeycloak.import=/tmp/nest-example.json part to at least have the container up and running which was a good decision until I realized that through Keycloak server GUI I cannot import nest-example.json. because it was throwing this error at me: "Import failed: Script upload is disabled"

Any help would be appreciated

Also I suggest to make the example easier to use. BTW I am on it and I will dockerize it in a way that you soly need to do a docker compose up

cre8 commented 11 months ago

@kasir-barati I had the same problem and solved it like this:

Important is the @Global() annotation and also to export the KeycloakConnectModule. After this the Guards will be available in all Modules that were imported in your AppModule.

Vitor-SO commented 11 months ago

@cre8 you have an example code of your implementation? I had a doubt about importing the configModule and the ConfigService inject

cre8 commented 11 months ago

@Vitor-SO this is copied from my working application. Where did you have problems with the imports? The ConfigModule and services are from the @nestjs/config that you need: https://docs.nestjs.com/techniques/configuration

Vitor-SO commented 11 months ago

@Vitor-SO this is copied from my working application. Where did you have problems with the imports? The ConfigModule and services are from the @nestjs/config that you need: https://docs.nestjs.com/techniques/configuration

@cre8 Ok! I thought the configModule was from some specific file of yours.

kasir-barati commented 11 months ago

@cre8 I tried your solution too (I mean the part that you added providers) but still no luck. I do not think our keycloak modules are any different from each other anymore: https://github.com/kasir-barati/you-say/blob/main/apps/backend/src/modules/keycloak/keycloak.module.ts

cre8 commented 11 months ago

@kasir-barati you forgot to export the keycloakmodule here: https://github.com/kasir-barati/you-say/blob/main/apps/backend/src/modules/keycloak/keycloak.module.ts#L35

Adding exports: [KeycloakConnectModule], to your script will fix it (tested it local). Otherwhise the providers you defined in the module will not be available for the other services.