I have a Docker compose
based system with back-end and front-end components. The back-end is written in Python Flask
and run in several docker containers and front-end is written in TypeScript
with Angular
. The front-end communicates with back-end via Restful APIs. The proxy is created with Nginx
. But the Keycloak
Token verification doesn’t work between front-end and back-end.
My KeyCloak
(and MySQL
) section of 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
Related Nginx
config part:
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 use the above /api/auth/verify
URL for every endpoints as verification. Eg.:
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
config for TypeScript
/Angular
:
export const environment = {
production: false,
keycloakConfig: {
url: 'http://localhost:8080/auth/',
realm: 'master',
clientId: 'frontend'
}
};
app-init.ts
:
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);
}
My app.module.ts
file contains the following section:
providers: [
KeycloakService,
{
provide: APP_INITIALIZER,
useFactory: initializer,
multi: true,
deps: [KeycloakService]
}
]
The getting error:
Config of frontend
client in Keycloak
:
My problem in points:
- The
Nginx
uses thehttp://keycloak:8080
URL which is the network inside the docker system (TheNginx
doesn’t see thelocalhost
fromDocker
). - The front-end (
TS
/Angular
) uses thehttp://localhost:8080
URL which is visible from outside (from the users’ browser) (In theory the front-end doesn’t see thekeycloak
network from user’s browser) - When I send a request from front-end which calls my API (which want to verify the token based on above
Nginx
example), I getInvalid Token
error - Based on my investigation I get this error because I get the token on
http://localhost:8080
URL and I want to verify it onhttp://keycloak:8080
URL.
Summarize of my used URLs:
- API’s URL:
http://localhost
- Keycloak URL inside Docker:
http://keycloak:8080
- Keycloak on front-end side:
http://localhost:8080
- Fornt-end’s URL :
http://localhost:4200
My question:
- How can I solve the above problem? I am very open for ideas.
1. EDIT:
If I have tried to set the front-end URL to http://localhost:8080
, and http://localhost:4200
but I got the below issue in both cases:
2
Answers
I have just found the solution!
The
Frontend URL
parameter is a quite misleading in theKeycloak
general configuration. My front-end is onhttp://localhost:4200
URL but as I mentioned in my question that URL wasn't working as front-end URL parameter in Keycloak (I have tested is many times).As you can see in my question in the configuration of
keycloak-angular
module theKeycloak
URL is set asurl: 'http://localhost:8080/auth/'
. If I set that URL asFrontend URL
parameter in theKeycloak
general configuration (or as input parameter indocker-compose.yml
file) my system works as charm.Note:
http://localhost:8080
) is not enough so the/auth
suffix is also needed (The full URL which is working:http://localhost:8080/auth/
).I am bit late,
but have you tried to add
127.0.0.1 keycloak
in your hosts file and replacehttp://localhost:8080/auth/
withhttp://keycloak:8080/auth/
in your Keycloak config forTypeScript/Angular
.Hosts File Location:
In Linux/Unix, its location is at:
/etc/hosts
In windows, its location is at
c:WindowsSystem32Driversetchosts
.Explanation:
The Nginx uses the http://keycloak:8080 URL which is the network inside the docker system.
The front-end (TS/Angular) uses the http://keycloak:8080
You will not get the invalid token error, as you are getting the token from http://keycloak:8080 and as well verifying with the same URL.