Open norricorp opened 4 months ago
hey john, i think i mentioned it in the article, but the more elaborate version was cut in the review phase by directus ;)
The Directus SDK is not saving Cookies with the HTTP-only Option enabled and we want to set the Cookie on the server, thus we need to access the Directus API directly from SvelteKit ourself and save the tokens in a secure cookie via SvelteKit's cookie handler.
in order to save the http-only cookie we need to use the SK fetch method. directus's sdk login function is not saving both cookies (i think they are only saving the access token if i remember correctly).
Certainly I am having problems with sveltekit and directus. In order to use named actions, it must be in a server file and so run on the server and though login works (and returns access and refresh tokens) these are, as you say, not available to the browser or even on the server, as a subsequent call to readMe fails with invalid credentials.
I am coming to this from a svelte / svelte-navigator project which I felt I had to migrate to sveltekit after svelte-navigator was no longer supported. I have tried to update navigator to svelte 4 but I can't get it to pass the cypress tests. I know where it is failing; I just can't work out why. My javascript just isn't good enough.
But thanks for this, it was just something that stood out for me as to why login wasn't being used.
i am currently on vacation so please take my remarks with a little bit grain of salt as i cannot confirm them 100%
run on the server and though login works (and returns access and refresh tokens) these are, as you say, not available to the browser or even on the server, as a subsequent call to readMe fails with invalid credentials.
i think that must have to do with some cookie policy. sounds like the browser is not saving them. look into the console. and follow the cookies, if they are returned by the directus API at some point you seem to "loose" them. if everything looks good until the moment you refresh and they are not in the browser, then it seems to be that the cookie domain or something is not correct. also on localhost you have to have ssl enabled if secure is true. the request after login should return a SET-COOKIE header. if not that is the first problem. if it does, then it have to be something with the cookie why the browser is not saving it.
I now feel quite guilty about chatting about such unimportant things when you are on holiday - hopefully somewhere warm but not hot (FYI - we have two hot days in coming in London!!). I think the problem is that page.server.js is running on the server, not in the browser, and though there are server cookies, they are not available to the authentication composable. The frustration is that the sdk authentication composable handles tokens and refresh automatically yet with sveltekit you are have written all of the extra code to do it manually. This may be heresy, but I am not convinced that sveltekit is making life easier. I do really like svelte and I stumbled across directus last year and am very impressed (though rewriting the sdk was a bit strange) but sveltekit ....
hehe no problem don't feel guilty. if i don't respond i am back on the hike :P
The frustration is that the sdk authentication composable handles tokens and refresh automatically yet with sveltekit you are have written all of the extra code to do it manually.
Yes unfortunately that is true.
page.server.js should run on the server. the server is setting the cookie, hence the name http-only cookie. again please have a look at the request in the developer console, you will very likely find your answer what is wrong there.
i get your frustration, i totally do. but the complexity comes mainly from sveltekits power (excellent SSR) and the fact that i opted for the most secure form of session persistence (http-only cookies). maybe try to relax the cookie by using the https://github.com/eikaramba/directus-sveltekit-starter/blob/main/frontend/src/lib/directus.js#L36 samesite: 'lax"
but it is nevertheless strange that it is not working for you locally with this repo cloned 100%. i tested it just 2 weeks ago i think.
A bit of a misunderstanding What is not working is my code, not your code. I have not run that.
Hi Eike, just a followup. I noticed that you do not use the composable client for your calls to Directus. eg client.login(email, pw) or client.logout(). Is there any reason for that? Such as the problems with sveltekit running on the server for api calls and therefore not being able to allow directus sdk to handle background stuff?
yes actually there was a good reason for it. it used to be that the Directus SDK is not saving both the access_token and refresh_token in cookie mode. it was only setting one of the tokens (i think the access_token?) so i needed to do the actual cookie handling myself.
HOWEVER, directus does now support a session cookie which is basically both token combined. i haven't looked into it yet but i believe one could now simplify the code and actually use the Directus SDK and would still have access to tokens on server side. If you are able to find out if that is working let me know for sure! I will not be able to find the time currently, but hopefully in a few months as i then have another directus/svelte project coming up.
Hi Eike, so I eventually got help on how to use the composable authentication and it now works. There is a cut down example on github under norricorp/sdauthtest. The key files are LoginModal.svelte (for login) and Header.svelte for logout. It's ugly but it demonstrates it. logout() works because a single instance of directus is used. So take a look at directus.js for that. Regards, John
Hi Eike, not really an issue, more a question. I read your two part blog on the directus site and you mention in part one that it is better to use the sdk over sveltekit's fetch. But then in part two, for login (and register) you use fetch. Is there any particular reason for not using the directus login(email, passwd) api? Regards, John