Keycloak is deprecating their client adapters (keycloak-connect) for Node and recommending openid-client as a replacement.
Setup Keycloak...
For further actions, you may consider blocking this person and/or reporting abuse
Just for information if you follow this but have no render feature installed in express, it will fail with "Cannot GET /testauth" even if it's connected.
Just use
res.send('You are connected');
instead ofres.render('test');
for the /testauth route.Since Version 0.6.0 of passport the "logout" method is asynchronous. The "logout callback" must therefore be changed to.
Maybe you can update your tutorial accordingly. (Your article was a great help!)
While trying to connect a vue application to keycloak using your code I noticed that there seems to be no further communication between keycloak and nodejs after a successful login. Once a session is created the validity of the connection between browser and nodejs is based on the validity of the session cookie alone.
In other words: If I end the session in keycloak by other means (e.g. logout by another client or by admin) then the express application won't notice.
Is this intended or did I make a mistake?
It looks to me like you switch from an oidc authentication to a http-cookie authentication.
Shouldn't there be a check in regular intervalls whether the user is still logged-in in keycloak? Or do you have an idea how this could beachived?
Hmm yea interesting problem, I didn't factor in logging out by keycloak admin or by another client my logic is only triggered when you hit the endpoint in express. Here is another example using bearer which might be better suited to your use case github.com/keycloak/keycloak/discu.... A regular check sounds like the way I would go , I don't believe that express-sessions has an event emitted on session expired. Without digging to much into it I would create another endpoint
/check-session
and poll it using fetch something likeI haven't tested it but it should probably work.
Thank you. But I finally decided to go for a different server technology. I never used NodeJS in a production environment before and I was rather shocked as I saw the long "todo list" for doing so. I don't feel inclined to study the 25th "library", "adapter", "plug-in" or whatever is necessary just to store session cookies.
So I came back to my good old PHP/Apache backend using "jumbojett" as on OIDC adapter.
However - I just wanted to let you know that I also rely on http sessions. But what I do to keep the connection to keycloak is: I store the access token in a session variable (in the backend) and with each AJAX request (it's a Vue SPA) I send the access token to keycloak to verify whether the user is still authorized.
So there are actually two sessions running (just like in your example), one in PHP/Apache and one in keycloak. And I need to make sure that the PHP session is at least as long (time-wise) as the keycloak session.
I believe this is something which would work in your example too.
Hey, Austin! Thank you so much for your article, I was able to make it work locally with it! :D
However, I'm facing some issues to run my application on docker. When I try to run both Keycloak and the application on containers, I receive the following error:
I'm running keycloak through docker-compose on port 8080 and using
http://localhost:8080/auth/realms/my-realm/.well-known/openid-configuration
onIssuer.discover
. When trying to access this link through the browser, it works normally.Do you have some hint on what may be causing it? I tried to tie a bridge network between keycloak container and nodejs container and it did not work also.
Thanks for taking the time to try this out in a docker container. So the issue is this line github.com/austincunningham/keyclo... where the localhost is the localhost inside the container and has no visibility on the global localhost (if that makes sense). Some solutions here how-to-connect-to-localhost-within... , I tried
to get the ip address and use that instead of localhost in the code and rebuilt the container
Looks to be working
There has to be a better way to get the docker0 ip address. This will get it
You can then create an environment variable
Change the issuer to use the environment variable
Can pass it in on docker run
For docker compose you can use a env file to pass in environment variables
Hey, Austin! Sorry for taking so long to reply, but I wanted to thank you for your help! It really helped me and worked like a charm! :)
Also, here's how I configured my apps on
docker-compose.yml
:Network:
Keycloak:
And Node app:
Hello Austin,
I was using keycloak-connect till now and it was working fine for me. As this adapter is getting deprecated I will try your solution for open-id client adapter, But I have a few questions regarding it.
Can we do role based and attributed encryption using it?
Can we protect the resources using this adapter?
As you will know that in the keycloak.protect() we can pass the roles and attributes. Also for protecting resources we can use keycloak.enforce().
Also we can pass the configuration to the keycloak using the previous adapter, can we do it with the help of this?
Thanks & Regards
Nikunj Mangla
Hi Nikunj,
Don't get me wrong here I loved
keycloak-connect
, it offered so much more out of the box thatOpenID client
does. OpenID client doesn't have this functionally as it is a generic client to be used with any OIDC provider. I am not sure without further investigation weather it is possible to pass roles within the auth flow or weather its possible to do something similar tokeycloak.enforce()
on resources, as for passing configuration I suspect that this functionality isn't available via OpenID client. These a all good questions It might be worth raising these with the Keycloak team github.com/keycloak/keycloak/discu... around the deprecation of the Node adapter.Regards,
Austin
Hi Ninkunj,
I was just reading down through the github discussions and looks like roles is possible see github.com/keycloak/keycloak/discu....
Regards,
Austin
Hello Austin,
Thank you for replying to my queries. I have also posted my concerns on the github discussion page. I will try with the roles checking through the link you provided. I am trying another module for now which is @keycloak/keycloak-admin-client not sure though if it will work or not for me. Let's see when they are going to provide a good support for the keycloak on nodejs
Did you manage to do cool stuff like role checking and resource checking with openid-client or any other 3rd party lib. I was trying to achieve the same goal with openid-client but I stuck. Now I am wondering how to check roles, resources, ...
Any update @austincunningham, @nikunjm10 ?
It was possible to do roles github.com/keycloak/keycloak/discu... there is an example in the discussion. It looks like
keycloak-connect
will be around for another while github.com/keycloak/keycloak/discu...When using keycloak-connect, a "kauth" object was available on the request object that included all sorts of useful information, including any custom user attributes that were mapped to the access token (kauth.grant.access_token). What would be the equivalent when using passport/openid?
I haven't used
kauth
before but can see how it would be useful. I had a look at the request object returned by passport/openid I couldn't see an equivalent togrant.access_token
in the request. So as far as I can see there is no equivalent tokauth.grant.access_token
.HI Austin! I am new to using keycloak, I am a bit confused on how to integrate this solution with a react application that is also secured by keycloak, can you lead me in the right path :)
This is not something I have done myself but I think this might cover it for you medium.com/devops-dudes/secure-fro...
Thanks for your reply, I´m doing most exactly like the article you send me but in this case for backend I´m not using the keycloak node adapter but the Keycloak Express Openid-client that is in your article. Right now I´m getting a valid token in my react app but when I´m sending this token in the headers of my requets and use the function that you created to check authentication I´m still getting that I´m not authenticated.
Do I have to trigger the route /test from the react app to set the req.isAuthenticate to true or I just have to check if the token I send it´s valid ?
Hey Ruben, as I've said its not something I have done so not too sure what advice I should give. I am curious
req.isAuthenticated()
should check for a valid token . It's something I would like to investigate when I have the time. If I figure it out I will post another blog.Hey, look at my repo: github.com/kasir-barati/you-say
I have a NestJS, and react app.
Thank you!
Hey, Austin ! Thank you for your article. But do you have such solution for Fastify ?
Hi Daniel, I haven't tried
Fastify
, but is now on my todo list. I will stick a blog up if I get it working.Hi Austin. Thanks for your article.
However when I run the application I am getting this error.
Hi David I can reproduce your error with the Keycloak server not running so you may not be running it on the default port
This makes sense as Keycloak's default port is 8080
Started up the keycloak server and was able to get it running