Best approach for NextJS and PHP API

I’m attempting to add Keycloak as the auth solution for our greenfield NextJS + PHP API project. From what I can tell, there are two options with this stack:

  1. Create a “confidential” client and use it with our PHP API. Redirect to Keycloak login page from a route, when we get back access and refresh tokens we store them in a session and give the session cookie back to the user. On authenticated route request, we load up the access token from the session, make sure it’s still valid, and either read it for the correct roles (if we decide to do access control with Keycloak) or look up the associated user in our database to get roles. At some point the frontend has to either get the Keycloak id token to store and read from to restrict access to frontend elements (if Keycloak is doing the access control) or we need an endpoint that gives user info based on what’s in our database that the frontend then stores somewhere.

  2. Create a “public” client that NextJS uses to get its own access, id, and refresh tokens. The php backend could be a “bearer-only” client that simply validates the access token sent from NextJS and reads the roles from it. With this approach the access control would have to be handled in Keycloak. We could leverage existing libraries for NextJS like react-keycloak/ssr or next-auth. However, storing tokens in the frontend like this seems to be inherently less secure (although could be mitigated with short expiration times).

My questions are:

  • What is Keycloak’s recommended approach for this stack?
  • Do you have experience with a similar stack, if so, which approach did you take?
  • Are option 2’s security implications something to worry about? We intend this to be a popular public facing site. I read in the book “Keycloak - Identity and Access Management for Modern Applications” that option 1 is preferred for a stack like this because of the security implications.
  • Those who let Keycloak handle access control with GBAC/RBAC/ABAC, do you have regrets wish this data was closer to to your application?

#2 is a great approach, and I have done it many times with a similar stack. Regarding your security question, the access token is expired quickly by default, and you can configure the refresh token to be rotated each refresh. This is a common use, and is not considered insecure.

Regarding your access control question, I don’t have much experience with Keycloak’s authorization features. I think it really depends on the complexity of your access control model. For many use cases, just using Keycloak Roles is sufficient.