Keycloak-angular: Cache the token

Created on 15 Jan 2018  路  29Comments  路  Source: mauriciovigolo/keycloak-angular

Is there a way to cache the Bearer in order to avoid another authentification after each page refresh ?

Question

Most helpful comment

Hi, I'm dealing with the same issue since the beginning of my project.
Command+r or cli refreshes redirect to keycloak login page everytime and asks for user/pass.
I have tried a lot of configuration combinations, but I couldn't make it work.
Until I saw this issue post, I started to think that this was the intended behaviour.

I will be glad if you can guide me to correct this workflow.
I have upgraded to Angular 6, also upgraded keycloak-angular to 3.0.1 as I'm using keycloak 3.4.3.

this is my app-init.ts:

      await keycloak.init({
          config: {
            url: environment.KEYCLOAK_URL,
            realm: '......',
            clientId: '.......',
            credentials: { secret: '..........' }
          },
          initOptions: {
            onLoad: 'login-required',
            checkLoginIframe: false
          },
          bearerExcludedUrls: [
            '/welcome$',
            '/workflows$',
            '/quickstart$',
            '/feedback$',
            '/contact$'
          ]
        });

I also tried with 'check-sso' option for onLoad parameter, nothing changes...

I don't have any other problems except for this issue.
Login works, login/logout redirections work, token expirations work, bearer tokens work, http interceptor works (attaches bearer token to every backend request) and backend verifies tokens successfully.

I can supply any other details if you need.

Thanks for this great package by the way. Other than the issue I'm trying to solve, everything is perfect.

All 29 comments

@ESSimon ,

Which flow are you using? The keycloak-js library already stores the bearer, deals with token refresh to always get a valid one. By authentication you mean all the authentication flow requested page -> login page -> requested page?

It might be an Angular CLI issue: when I make any changes to a file, I get the auth flow requested page -> login page -> requested page

Hi @ESSimon, how are you?

Sorry for the delay to answer you, I'm on vacation these days, so sometimes depending the location I'm completely offline :smile: .

About your problem It doesn't seem to be a problem with the angular cli.
Every time the page is edited, webpack is watching for changes and trigger a full page reload at the browser. So, the keycloak-js will look for a token stored at you browser session and send it to the keycloak server instance for validation. If your token is not valid anymore it will send you to the login page.

Just a question, is the behavior looks like an infinite loop? Going from the app -> keycloak server -> app and in the end it goes to the login page? I've had a similar situation and it was related to the iframe stored as described in Keycloak-5022. If this solution doesn't help you, take a look in this one: keycloak-4338 or keycloak-5065.

Hope it helps!

No problem, enjoy your vacations :)

It doesn't infinite loop, it's just a minor inconvenience for the development flow. Every changes in the code make the page refresh twice (regular refresh => then Angular bootstraps => then Keycloak server => then Angular bootstraps again). The token might get deleted somehow, I'll look into it. Thanks for the pointers

Hi @ESSimon .. did you ever find where the token get's deleted??

If not I will try and look into it .. but maybe you had solve the issue already.

Thanks

Sorry: I heavily optimized the startup time using lazy load and removing tons of unneeded dependencies, so I still have the same issue but it doesn't really matter anymore for me :/

@fmq, are you facing the same problem?

@mauriciovigolo yes, basically the issue is that on every reload of the page (Command+r or ng cli reloading the page) I'm required to login again.

As Mauricio stated it's a minor inconvenience at development time, it's not breaking.

The only thing I'm worried about (I have not deployed the app yet) is that on every refresh of the page the user will face the same issue regardless of the token validity.

Thanks.

Hi @fmq, thanks for your feedback. I have been using this version in production and did not face this issue.
Try to start your angular cli with the ssl enabled, I think it may be some issue related to it. The drawback is that all your dev servers will have to use https....

Let me know if it helps.

Thanks @mauriciovigolo I will eventually give it a try, right now I have SSO running in a local Minishift and I would have to move everything to ssl.

I will test this over the weekend and let you know how it goes.

TIA!

Hi, I'm dealing with the same issue since the beginning of my project.
Command+r or cli refreshes redirect to keycloak login page everytime and asks for user/pass.
I have tried a lot of configuration combinations, but I couldn't make it work.
Until I saw this issue post, I started to think that this was the intended behaviour.

I will be glad if you can guide me to correct this workflow.
I have upgraded to Angular 6, also upgraded keycloak-angular to 3.0.1 as I'm using keycloak 3.4.3.

this is my app-init.ts:

      await keycloak.init({
          config: {
            url: environment.KEYCLOAK_URL,
            realm: '......',
            clientId: '.......',
            credentials: { secret: '..........' }
          },
          initOptions: {
            onLoad: 'login-required',
            checkLoginIframe: false
          },
          bearerExcludedUrls: [
            '/welcome$',
            '/workflows$',
            '/quickstart$',
            '/feedback$',
            '/contact$'
          ]
        });

I also tried with 'check-sso' option for onLoad parameter, nothing changes...

I don't have any other problems except for this issue.
Login works, login/logout redirections work, token expirations work, bearer tokens work, http interceptor works (attaches bearer token to every backend request) and backend verifies tokens successfully.

I can supply any other details if you need.

Thanks for this great package by the way. Other than the issue I'm trying to solve, everything is perfect.

@mehmetzahid, I will take a look on this problem. Thanks!

As I understand the default behavior is:

request a page > get redirect to kc server (it appends query params to redirect url > load initially requested page with new query params that are used to fetch the token.

And this thing happens every time you refresh a page.

Is it even possible to obtain a token without being redirected to kc page if you are logged in?

Is it even possible to obtain a token without being redirected to kc page if you are logged in?

It works if you are in --prod mode with Angular CLI

It works if you are in --prod mode with Angular CLI

Not sure how this is affected?

No idea, maybe a cache/context cleaning mechanism built in the auto-refresher ?
Or a slightly different bootstrapping cycle in Angular in JIT and AOT mode ?

I am not using angular cli actually, but same behavior is seen when I build in production mode as well. Could you check when you are in prod mode and set chrome's network console to "Preserve log" to see if your bundle is loaded twice?

Damn, it's loaded twice indeed...

@dmnrmr, thanks for reporting. By loaded twice you mean two requests to initialize the library or the authentication workflow being executed twice?

Let me illustrate a case for already logged in user.
Let's say front-end is running on http://localhost:4200 and keycloak server is running on http://kc.srv

When I open front-end:
> request http://localhost:4200
> request bundle.js
> redirect to http://kc.srv/auth
> request http://localhost:4200 with bunch of query parameters that were appended on previous page
> request bundle.js
> request http://kc.srv/auth/token

This results in page loading twice, but with small bundle sizes and gzip compression is barely noticeable.

And this all is with "normaL" flow. Keycloak also allows to use "impolicit flow" when token would be appended during first visit of kc page (it only eliminates additional call for token).

If you check keycloak typings you could see that there are these init options:

token?: string;
refreshToken?: string;
idToken?: string;

I tried to init kc with token, but I still got redirected to kc auth page so it didn't work for me.

EDIT:
Keycloack doesn't store any authentication related info on the http://localhost:4200. It has cookies stored in http://kc.srv thus the redirect to get them.

I have a simular issue, i would love the option to store the token in a cookie so a page-refresh doesnt redirect you to keycloak and back everytime i do F5 or send a link to someone.

@dmnrmr thanks for sharing the workflow. The redirect during initialization, even if the user is logged in, is a behavior from keycloak-js adapter and right now I don't have any plans to customize the official js adapter.

There is a topic at Keycloak JIRA related to this issue. In summary they opted for security instead of a better UX or performance.

If this is a desirable feature you still may open an issue at keycloak JIRA. Any future releases of keycloak-js will be updated in keycloak-angular.

Thanks for this information,

sorry for reopening this issue, but now I integrated your package in another project of mine.
in this second project, keycloak does not require user/pass login on browser refreshes.
there are several differences between two projects, but the most important difference is that second project is hosted on https with ssl.

so there is absolutely something wrong that depends on configuration or environment.

if you need more information about the workflow (i.e. the requests on page load etc) I can try to provide...

@mehmetzahid, no problem for reopening. This is happening in your machine or in an app in production or hosted in a test environment?

first project, where keycloak needs login on every browser refresh is tested both locally on my machine and a test environment. the behavior did not change.

for the second project, where the browser refresh does not asks for user/pass input is hosted on a tet environment very close to the same test environment above.

as of now, we havent get any products to production using keycloak.
we are still trying to see if we can depend on keycloak (not just this issue, checking several things)

@mehmetzahid, I had this kind of issue during development and using angular-cli. In applications deployed in a test or production environments don't. I need to do a better investigation about it, however I guess that, locally the generated build from a code update may interfere and also the keycloak server in https and locally http.

But as I said, this is only a guess I need to take a closer look to this development refresh problem.

Hi @mauriciovigolo i am using keycloak in my agular 7 application. after login application get reloaded again again.
after adding "checkLoginIframe" : false [
this.keycloakAuth.init({ onLoad: 'login-required',"checkLoginIframe" : false }) ] this issue get resolved, but same code base was working fine withoud adding this property earlier. can you please tell me why suddenly it starts behaving like this.
expecting kind replay from your side . Thanks in advance.

@ajinkyabapat1 Please create a new issue, with enough information to reproduce it. We do not keep track of conversation in closed issues.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ValentinBossi picture ValentinBossi  路  4Comments

jderuere picture jderuere  路  4Comments

ayoubnejm picture ayoubnejm  路  3Comments

czeckd picture czeckd  路  4Comments

unib1t picture unib1t  路  4Comments