In my system, I have a setup based on Docker compose with back-end and front-end components. The back-end is developed using Python Flask and runs in multiple docker containers, while the front-end is coded in TypeScript with Angular. Communication between the front-end and back-end is established through Restful APIs, and Nginx acts as a proxy. However, there is an issue with Keycloak token verification between the front-end and back-end.
Configuration of KeyCloak (and MySQL) in the docker-compose.yml file:
mysql:
image: mysql:5.7.31
ports:
- 9988:3306
volumes:
- keycloak_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: keycloak
MYSQL_USER: keycloak
MYSQL_PASSWORD: password
networks:
- auth_net
keycloak:
image: jboss/keycloak:13.0.1
environment:
DB_VENDOR: MYSQL
DB_ADDR: mysql
DB_DATABASE: keycloak
DB_USER: keycloak
DB_PASSWORD: password
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: admin
PROXY_ADDRESS_FORWARDING: "true"
ports:
- 8080:8080
- 8443:8443
depends_on:
- mysql
networks:
- auth_net
Nginx configuration related to the issue:
location /api/auth/verify {
internal;
proxy_method POST;
proxy_intercept_errors on;
proxy_pass http://keycloak:8080/auth/realms/master/protocol/openid-connect/userinfo;
error_page 400 =401 /401.html;
}
I am utilizing the above /api/auth/verify URL for authentication purposes in all endpoints. For example:
location /api/users {
auth_request /api/auth/verify;
rewrite ^/api/(.*) /$1 break;
proxy_pass http://users:6000;
proxy_pass_request_headers on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
My Keycloak configurations for TypeScript/Angular:
export const environment = {
production: false,
keycloakConfig: {
url: 'http://localhost:8080/auth/',
realm: 'master',
clientId: 'frontend'
}
};
app-init.ts content:
import { KeycloakService, KeycloakOptions } from 'keycloak-angular';
import { environment } from 'src/environments/environment';
export function initializer(keycloak: KeycloakService): () => Promise<any> {
const options: KeycloakOptions = {
config: environment.keycloakConfig
};
return (): Promise<any> => keycloak.init(options);
}
The app.module.ts file includes the following section:
providers: [
KeycloakService,
{
provide: APP_INITIALIZER,
useFactory: initializer,
multi: true,
deps: [KeycloakService]
}
]
An error message that I encountered:
https://i.sstatic.net/Cw1d4.png
Apeek into the frontend client's configuration in Keycloak:
https://i.sstatic.net/Nk7RY.png
The issues summed up:
- The Nginx uses the http://keycloak:8080 URL which works within the Docker network but not with localhost.
- The front-end (TS/Angular) uses http://localhost:8080 URL which may cause compatibility problems with the Nginx configuration.
- When a request is made from the front-end to authenticate via the API using Nginx, an "Invalid Token" error occurs.
- Based on my research, this error seems to stem from using tokens generated at http://localhost:8080 to authenticate at http://keycloak:8080.
Summary of URLs utilized:
- API's URL: http://localhost
- Keycloak URL inside Docker: http://keycloak:8080
- Keycloak on front-end side: http://localhost:8080
- Front-end's URL : http://localhost:4200
The question at hand:
- How can I resolve the aforementioned issue? Any suggestions would be greatly appreciated.
1st EDIT:
Although I attempted setting the front-end URL to http://localhost:8080 and http://localhost:4200, both resulted in the below issue: