- great visualisation - mentioning issues many devs faced (e.g. confusion about 'locals -> local storage') - information apply for Typescript AND Javascript devs - great detail Thank you so much! You are helping sveltekit users so much! Please keep going :) Potential future topics: - error handling - integrating payment solutions (stripe, PayPal)
Great Video!! One think that we have to keep in mind is that handle hook doesn't get run for every request received by server. for example a route without a load function doesn't invoke a handle hook.
@@Huntabyte I'm using this now with firebase passwordless login with email link authentication for a client project. This is the best "no fluff" channel for intermediate sveltekit.
ATTN: I’ve heard this comment multiple times so I need to address it to stop the spread: Do not solely use +layout.server to handle auth for a bunch of routes, unless you are awaiting parent on every subsequent +page.server. Watch this video for more info: ruclips.net/video/UbhhJWV3bmI/видео.html
Another quality tutorial to compliment your growing SvelteKit playlist. As a beginner, I find that the diagrams make it much easier to understand the process and the dialog/interaction between the various steps in the system as a whole. It is very daunting to open up the SvelteKit documentation and know where to start, having just a basic understanding of web development. Having someone brighter and more technically gifted to lead the way is a real privilege. I really appreciate you giving your time, effort and energy. I hope to see you around far into the future and wish you every success with your channel.
Thank you Sir so much for explaining hooks, locals, protected route so clear, I finally know how to handle authentication with Sveltekit, you are live saver 🙏😭
@@Huntabyte what if the auth token expires? For example, if I make a call to my API (in my case strapi) and it returns token expired error. Do I return that error from every page.server.js file? Or is it better to check token expiration time beforehand in handle method? What is the proper way of handling that?
I didn't understand why someone would do this, but then It literally came to me in my sleep why this is a good solution. I also read up about this on git and sooo I tried to implement it. Soo much easier, cleaner and safer. Thanks for the explanaiton.
Thank you for sharing. However, when I use group layout(), I encounter an issue where the URL is not received within the hook, and if I place it outside, the layout is not separated between routes.
17:38 if you want to move it down without the mouse you can simply hold alt and then use the arrow keys to move it up or down. Also if you hold shift + alt and then use the arrow keys you can duplicate the selected line(s) :)
found your channel and really loving it. I have been tasked with build a simple application for onboarding customers. I am pretty much a backend dev but sveltekit has become my goto framework for when I need it. Your content is really amazing, I have learnt so much
Interesting to see how Svelte does middleware. Its a shame they don't just call it that. I feel a lot of us with experience know what middleware is. These new frameworks just love the word "hook" lol. Thanks though this video really helped, be wrap my head on how svelte does this.
Great video! I do have a quick question though. In the Admin protected route section, will this work if you were to provide a link to this section so that the application routes client side (instead of directly typing the route in the address bar)? I think if the admin route doesn’t have a +page.server.js file, then the hook will never run meaning if the user was logged out while on the page with the link, they could still navigate to the admin route. Any thoughts here would be appreciated. It’s something I am struggling to figure out a way around at the moment.
@@Huntabyte I was wondering if you could publish your (awesome!) hooks graphic and add it to the video description? This is very good teaching material.
That is very awesome, good explanations and great topic, you made me understand the hooks. Does it work with another backend than sveltekit like node js? I have tried but without any success.
Idk if it's me but the handle hook only get called once when the page is fetched. If the user then navigates you need client side code that prevents the user from beeing ablte to access your content. That's why I now have both within my code. Maybe someone know whats wrong?
It is important to note that this wouldn't work for client side navigation, as the Handle hook would only run when requests are made to the server. If svelte assumes it wouldn't need to call the server, when you go to `/protected` you would still be able to access it even when logged out. I think for you it calls the server, because you have a `protected/+page.server.js` that does nothing. If you remove that you would probably be in trouble.
@@guhkunpatata3150you've probably figured this out already but for anyone else, you could use getSession in a hooks.client.js file, read your cookie for eg an access token and redirect if the user was logged out.
Awesome, this was so helpful! Thanks! Do you have a strategy for components too? For instance if you wanted to render markup conditionally in the main nav (like showing a login button if the user isn't logged in yet). How do you keep it reactive?
seems like file hook.server.ts only triggered when making request to server side. when browsing in client side, its not working. please help any suggestion ? thanks before
thanks, for this! 2 quick questions - given we already have the hook.server.ts which handles the redirect do we need the load function or even the +page.server.ts file (setting aside that you need it for simulating a login in this case) in the base of the routes folder? - how do you decide if the hook file should be a server.ts or or just a ts file? thanks again! love the content :)
Great video, appreciate the straightforward approach! One question: how would you approach consuming the session/user data in the protected routes themselves. Type-wise, the session and user objects can both be undefined, and +page.server is not "aware" that the auth check has been done in the hooks already. So the options are to either do a non-null assertion, or do the session null check + redirect in +page.server again, even though it has already been done in the hook. Any other option which would be cleaner?
I had problems with this technique in my own code: after logging out, i redirect users to the login page. But the user is able to go "back" to the protected page, and still use the nav menu to go to another protected link and it would STILL load that page (and not redirect to login page like it should.) The only simple solution I found is to disable csr. With this solution, the user could go back, but clicking a link to protected route would correctly redirect to login page.
Fantastic video! I first watched your "don't protected with layouts", and then watched this... You helped me understand a ton about the page building process, and where to intercept the authentication checks. I really appreciate it. One question, if you put all of your protected content under a "(app)" folder using parenthesis, how should we update the event.url.pathnamne.startsWith function? (around 13:55 in). How to apply the hook to every page within a group?
Hey, I'm just starting to learn Svelte, or really making webapps in general, and just want to thank you for your awesome content so far, that I was able to discover yesterday and today. I noticed you did some videos on Supabase and Pocketbase, and while I really like Supabase, their selfhosted version is not as feature rich and usable as their cloud version. An interesting alternative to those two is Appwrite, wich selfhosted version gives you the same experience as their hosted one. Would it be possible for you to make some basic tutorials about Svelte and Appwrite, like securely loggin in users, with it? I'm a bit unsure how to use handle routes together with appwrite for securing access. Thank you again for your awesome tutorials :)
Thanks for the comment! I have explored AppWrite in the past but they didn't have solid SSR support, things may have changed though, so I will look into revisiting!
if I have a separate backend server running, and I want to make a fetch call which passes a cookie, what do I have to do for Svelte to let me pass the cookie? I've looked at the documentation, but handleFetch doesn't seem to work for me. The backend server is on the same machine, just on a different port.
Hunter, I could be mistaken but at about 16:17 in the video, when you're demonstrating that a user with a regularusertoken would be unable to access the '/protected/admin' route, it looks like you were able to access the route with the regularusertoken. Was there something misconfigured there - I haven't been able to grab the repo and go through it yet, thank you.
I couldn't, I was stupid and for some reason had the `h1` tag on the '/protected' page say "Admin". If you look again the /protected page has a title of `Admin` and '/protected/admin' has the title of Admin Page!
If I go to the admin page using an anchor link it bypasses the hook, it only runs if there is a +page.server file inside the admin folder, however if done as a hard redirect it checks the role
hunter love your videos! Could you possibly make a video about middlewares? Im thinking of multitenant with subdomain for each tenants and I think this is doable via using a function in +layout.ts but not sure how, another option is using node/express adapter. Do you know how to do it, can you possibly cover it in a video? Thanks!
I've been looking into this a bit myself, once I get through a few others things I'm working on, I will spend a bit more time on it and probably create a video!
So how do we do if we want the handle to be run on client-side routing as well? I have some pages that are not super important to guard, but I still want to redirect if the user got logged out for some reason. Now they can still navigate in the app client side when the cookie is removed.
Thanks for this great tutorial. After I wached that video I downloaded the coding from git because "LOGOUT" doesn't worked correctly in my coding. The cookie is not deleted and still I don't know why. After I downloaded your coding from git plus installation, the issue is stile there. Do you have any advise, why the cookie is not deleted?
Great video ! But I have a problem, if I delete the cookie and navigate with the previous page button of my brownser, i can still reach protected route unitl I refresh the page manualy. This is the same problem that explain in the next video "Stop using +layout for auth", thanks
Something than I found is every route than you want to protect you have to create +page.server.ts file, Are there something different to that? thank in advance
I get the above, but what happens if you have a link Href on the Layout or Nav bar, and a user click on it to go to a /protectedpage ? I'm finding the above doesn't prevent a user from doing that :S ? Am I missing something? Edit: every protected page must have a server side function, otherwise it will bypass the hooks and be rendered as a static site page! I used a console log during testing to trigger this 👌🏾 works!
Great video, thanks for putting it (and others) together. One thing I don't understand though, it seems that your protected route requires protected/+page.server.ts to exist (even if empty) in order for the handler hook to fire from a link. If you remove protected/+page.server.ts you will see that the hook is not run unless you manually navigate to it by typing in the URL (e.g. localhost:/protected). Is Sveltekit intended to work this way? Seems like a variation of the naive layout issue you referenced elsewhere in comments that could lead to dangerous consequences if you somehow forget to put an empty +page.server.ts file there.
I believe it is intended to work that way, as having a +page.server tells SvelteKit there’s something needed from the server to load that page (even if it’s empty). There are open discussions on GitHub about this and the idea of making protecting routes more obvious, something like a +auth.server. Hopefully the maintainers can make a decision and move quickly, as there are many outstanding ‘gotchas’.
@@Huntabyte Not sure if there is something for this yet. but so far I really dont like doing protected routes in sveltekit, it feels very janky / an afterthought compared to more established frameworks. Having to remember to put an empty +page.server.js in order to protect each individual route kinda makes the hook feel almost as janky as the layout.server.js, additionally at least with the layout.server.js It is nested which routes are protected, while I have to specify each route for the hooks solution. Both are kinda just trash tbh.
@@Huntabyte could the same need for +page.server be done at the root of that path with a +layout.server.js to ensure that hooks.server is run? In some initial testing I put a a +layout.server at /my, and when navigating to /my/info/profiles or /my/info, hooks.server did fire. I am not sure if this is foolproof or not and am wondering what others think of the approach.
Hey, uhm, I don't know if I'm doing something wrong, because uh... it works for the most part, except that the client-side router may still execute the load function of a protected route when it's preloading that protected route as a response to the user hovering over a link that points towards a protected route. So I still get a console log in my browser that basically says "fetching sensitive data". It seems like in that scenario, the hook on the server is not being invoked. Do you have any tips for that? Or do I just have to disable preloading?
Thank you for a great video! Can you please tell me if event.locals object is different for every user? So i dont get leaks between different users' sessions? Sorry for a perhaps dumb question but i'm just starting... Thanks again!
It is not only unique to each user, but unique to each request even from the same user. Locals is created and only lives for the duration of each request!
Just implemented some authentication thanks to this video. But what would be the best practise to save cookies into local storage to access the user info globally? For example, I have a Navigation.svelte component in the root +layout.svelte (where i want to display the user email) but I don't want to have every page request on the server side. But since the auth.js, hooks.server.js, and registration are done on the serverside, where should I save the cookies to the local storage? Should I have some condition in the root layout.svelte component when the cookie is set? Or should I just access the cookie in the .svelte files directly? Thanks for any help :)
At 13:30, you demonstrate protected an entire path with hooks.server.ts. Then you say, "you're still going to want to ensure users aren't trying to create items for other users and things like that . . . ." Can you elaborate on what you're referring to? Are you referring to row-level security on the database side, or to some other checks? Also, I'd love a tutorial tying together SvelteKit protected routes and Supabase authentication.
I find this easier to do by just moving whatever routes in to a route group like `(unauthenticated)` and `(app)` then making a `+layout.server.ts` that does the check of user is logged in or user role etc and doing the redirect there. That way you can apply to all the routes w/out relying on hardcoded route strings and having to prepend a path like `/protected` to it.
Layout load only runs when the first route of that layout loads. So you aren’t actually checking auth status with every request to a protected resource, only the first protected resource. There’s actually an issue open right now on this exact issue: github.com/sveltejs/kit/issues/6315
Put a console log inside your layout load. Navigate to /protected then click a link in your app that takes you to /protected/item. If you directly navigate through the URL, that will trigger the layout load to rerun, however, if you navigate through your app (through a link or nav menu), the layout load will not rerun unless you exit that layout tree and re-enter it. I had to investigate this quite a bit, but when I found the gaping hole in my security I've been advocating against that way of doing things. It's on the SvelteKit post-1.0 roadmap to be addressed, so I'm interested to see how they handle it. I will create a video on this most likely.
hook only run which route have +page.server.ts file if you navigate any route inside produced path without have +page.server.ts using button it will navigate because hooks.server.ts not run
I got an empty object when console logging... after 20min I found out it was because I named the hook file `hook.server.ts` and not `hooks.server.ts` ......................
hi, great video and it is really helping me in my project. But a quick question, is it secure doing it this way? I mean we are using cookies to handle authentication and I just managed to land on the admin page by just changing the value of the cookie in my browser (with a cookie editor) from "regularusertoken" to "adminusertoken". Just like that I was able to land on to the admin page. I have heared about cookie steaaling and such but I wanted to ask if the case I am describing is the same as cookie stealing or is the issue with the way we are handling the request? Because in the current scenario any user can just log in to our site as admin without much trouble at all. Thanks
wouldn't this just clutter your handle hook? you'd be mixing permission checks along with user auth and probably some more stuff in one hook. wouldn't it be better to just check for permissions on each subsequent route with pageserverload? of course the benefit of handling all of it in the server hook would be that you have it one place but other than that i see no real advantage of this over checking it in the load function of each page. i may be wrong though and if i am, please do tell.
I typically do check in each page server load, however, for a massive group of routes like '/admin' where everything has auth requirements, this is an easy way to handle it.
@@Huntabyte ah i see. since there can be a lot of nested routes you may want to group them in the handle hook. gotcha. great sveltekit content btw, keep it up!
Wait, is this the best solution that we have? This is terrible, basically we disable CSR, so every request goes back to the server in order to check the secure cookie... There's got to be a better way.. BTW do we even care if the user deletes their token? We have to revoke it server side anyway. Am I missing something here?
I get the following Error: Error: Parse failure: Identifier 'Handle' has already been declared (3:11) I´m at 5:09 in the Video and my Code in the hooks.server.js is: import {Handle} from "@sveltejs/kit" export const Handle = async ({event, resolve}) =>{ const response = await resolve(event) return response } Does anyone know what i´m doing wrong?
@@Huntabyte ist that also for the next step in the +page.server.js? Because I get this error : Error: Invalid export 'PageServerLoad' in src/routes/+page.server.js (valid exports are load, prerender, csr, ssr, actions, trailingSlash, config, or anything with a '_' prefix) My Code: export const PageServerLoad = async ({locals}) => { console.log(locals); }
- great visualisation
- mentioning issues many devs faced (e.g. confusion about 'locals -> local storage')
- information apply for Typescript AND Javascript devs
- great detail
Thank you so much! You are helping sveltekit users so much! Please keep going :)
Potential future topics:
- error handling
- integrating payment solutions (stripe, PayPal)
You and Joy Of Code are doing amazing things in the Svelte community. Keep it up. I have been watching y'all a lot.
Thank you!
Hi. Any other channels/places would you recommend to learn Svelte? I'm new to SvelteKit and Supabase
@@WaelMx these 2 plus the docs will be enough. Trust me. I myself learned from the docs alone.
@nyashachiroro2531 Thanks a lot for your response!
Great Video!! One think that we have to keep in mind is that handle hook doesn't get run for every request received by server. for example a route without a load function doesn't invoke a handle hook.
Just like with form actions, you are breaking down another advanced topic within Sveltekit. This video + using it in my own project = level up.
That's great to hear!
@@Huntabyte I'm using this now with firebase passwordless login with email link authentication for a client project. This is the best "no fluff" channel for intermediate sveltekit.
ATTN: I’ve heard this comment multiple times so I need to address it to stop the spread: Do not solely use +layout.server to handle auth for a bunch of routes, unless you are awaiting parent on every subsequent +page.server. Watch this video for more info: ruclips.net/video/UbhhJWV3bmI/видео.html
Hey Hunter! If you can make your VS code font as big as your h1 it'll be so much easier to watch your videos on the phone
Another quality tutorial to compliment your growing SvelteKit playlist. As a beginner, I find that the diagrams make it much easier to understand the process and the dialog/interaction between the various steps in the system as a whole. It is very daunting to open up the SvelteKit documentation and know where to start, having just a basic understanding of web development. Having someone brighter and more technically gifted to lead the way is a real privilege. I really appreciate you giving your time, effort and energy. I hope to see you around far into the future and wish you every success with your channel.
Thank you so much for the kind words, I greatly appreciate it and am very happy that you find the content useful!
Very informative and in plain English. Thank you
Thanks, Stan!
Thank you Sir so much for explaining hooks, locals, protected route so clear, I finally know how to handle authentication with Sveltekit, you are live saver 🙏😭
You’re very welcome, Mask Man!
@@Huntabyte what if the auth token expires? For example, if I make a call to my API (in my case strapi) and it returns token expired error. Do I return that error from every page.server.js file? Or is it better to check token expiration time beforehand in handle method? What is the proper way of handling that?
I didn't understand why someone would do this, but then It literally came to me in my sleep why this is a good solution. I also read up about this on git and sooo I tried to implement it. Soo much easier, cleaner and safer. Thanks for the explanaiton.
Wow, Thank you, sir. That is a straightforward and to-the-point description of Handle hook's usage.
You're very welcome!
Thanks to you learning SvelteKit has been nothing but pleasure. Absolute life saver, thank you so much.
You’re very welcome!
I’m working on authentication with SvelteKit right now and this is hugely helpful! Thanks so much
Great to hear, you're very welcome!
Thank you for sharing. However, when I use group layout(), I encounter an issue where the URL is not received within the hook, and if I place it outside, the layout is not separated between routes.
You're such a blessing to this world
This was the missing video I really needed, thank you very much for all your insightful videos on the subject of Svelte(Kit), but especially this one
SVELTEKIT 1.O OFFICIALLY RELEASED. 🤩
I was using it in this video ✅
Thanks so much, I'm finally beginning to use SvelteKit at its full potential!
That's great to here! Thanks for becoming a channel member, it means a lot!
++ on the route protection trick with the handle hooks!
I’m a for hook route protections!
This is EXACTLY what I was looking for, great example and even better explanation.
Thanks a lot!
17:38 if you want to move it down without the mouse you can simply hold alt and then use the arrow keys to move it up or down. Also if you hold shift + alt and then use the arrow keys you can duplicate the selected line(s) :)
I do actually use those shortcuts quite a bit (if you watch my streams/other videos), for some reason I just choose not to sometimes 😂
OMG finally I get what locals means, thank you so much 👍
Fantastic video. Very clear and concise. Much appreciated. Thank you.
I'm glad to hear that, you're very welcome!
What a great Svelte/SK resource! Thank you
Great video, really helped me understand the locals concept! Thanks a lot! 😄
Glad to hear that! You're very welcome and thanks for taking the time to comment!
found your channel and really loving it. I have been tasked with build a simple application for onboarding customers. I am pretty much a backend dev but sveltekit has become my goto framework for when I need it. Your content is really amazing, I have learnt so much
That's awesome to hear, thanks for taking the time to comment!
Your videos are so great! Thanks for posting them 🙏👌
You’re very welcome, and thank you for the kind words!
Damn, I think this is the exact thing I am looking for. Very good video, ty!
Best channel for svelte
Thank you!
Thank you very much! Clear explanation! It helps to make progress!
Banger video, you can also do (procected) directory to still use layouts without creating a subdirectory for the routes
Handling Auth in Layouts without properly calling `await parent()` on every subsequent +page.server is not secure: github.com/sveltejs/kit/issues/6315
@@Huntabyte Oh how strange, let me fix that real quick before deploying haha, you're a lifesaver, will they address this or will this be how it is?
@@Hugos68 I'm posting a video on this in a few minutes :) which will include a workaround if you do prefer to use layouts.
insane guide, I have to say. This helps me alot
Awesome content as usual. Thanks for making this!
You’re welcome!
Very useful info using hooks, can't wait for your other lessons in the sveltekit series ❤❤
I'm glad you found it useful!
Interesting to see how Svelte does middleware. Its a shame they don't just call it that. I feel a lot of us with experience know what middleware is. These new frameworks just love the word "hook" lol. Thanks though this video really helped, be wrap my head on how svelte does this.
Another banger!! 🔥🔥🎉
Thank you!
Thanks! Great video!
You're very welcome!
Great video!
I do have a quick question though.
In the Admin protected route section, will this work if you were to provide a link to this section so that the application routes client side (instead of directly typing the route in the address bar)? I think if the admin route doesn’t have a +page.server.js file, then the hook will never run meaning if the user was logged out while on the page with the link, they could still navigate to the admin route.
Any thoughts here would be appreciated. It’s something I am struggling to figure out a way around at the moment.
Having the same issue, hard to think the creator of this video did not notice this.
I was thinking the same thing. Although the video was good author doesn’t discuss how to stop client side navigation.
Great explanation. Thanks 👍 you might want to try sveltekit auth which vercel just announced
I'll certainly look into it!
Very useful and very well explained, thank you!
You’re welcome!
@@Huntabyte I was wondering if you could publish your (awesome!) hooks graphic and add it to the video description? This is very good teaching material.
What an awesome video - explained everything so well
Phenomenal video. Thanks!
You’re welcome!
That is very awesome, good explanations and great topic, you made me understand the hooks.
Does it work with another backend than sveltekit like node js? I have tried but without any success.
Idk if it's me but the handle hook only get called once when the page is fetched. If the user then navigates you need client side code that prevents the user from beeing ablte to access your content. That's why I now have both within my code. Maybe someone know whats wrong?
It is important to note that this wouldn't work for client side navigation, as the Handle hook would only run when requests are made to the server. If svelte assumes it wouldn't need to call the server, when you go to `/protected` you would still be able to access it even when logged out. I think for you it calls the server, because you have a `protected/+page.server.js` that does nothing. If you remove that you would probably be in trouble.
ah yes this is true, this is need to mentioned!!!
any idea how to handle this ?
prolly disable csr@@guhkunpatata3150
@@guhkunpatata3150you've probably figured this out already but for anyone else, you could use getSession in a hooks.client.js file, read your cookie for eg an access token and redirect if the user was logged out.
Ok so we add "+page.server.ts" to every route, that fixes the issue right?
Great tutorial!
Thank you!
Awesome content!
Thank you!
Awesome, this was so helpful! Thanks! Do you have a strategy for components too? For instance if you wanted to render markup conditionally in the main nav (like showing a login button if the user isn't logged in yet). How do you keep it reactive?
easiest subscribe in a while. here for it.
just send a few coffees your way, thank you!
Hey I appreciate that! Thank you!!
@@Huntabyte well deserved!
Keep it up bro. I support you.
I kinda wish having group-scoped hooks in the future 😊
thanks for the great explanation!
seems like file hook.server.ts only triggered when making request to server side. when browsing in client side, its not working. please help any suggestion ? thanks before
Great video!!
thanks, for this! 2 quick questions
- given we already have the hook.server.ts which handles the redirect do we need the load function or even the +page.server.ts file (setting aside that you need it for simulating a login in this case) in the base of the routes folder?
- how do you decide if the hook file should be a server.ts or or just a ts file?
thanks again! love the content :)
Great video, appreciate the straightforward approach!
One question: how would you approach consuming the session/user data in the protected routes themselves. Type-wise, the session and user objects can both be undefined, and +page.server is not "aware" that the auth check has been done in the hooks already. So the options are to either do a non-null assertion, or do the session null check + redirect in +page.server again, even though it has already been done in the hook.
Any other option which would be cleaner?
Great video
Thank you!
thank you!
I had problems with this technique in my own code: after logging out, i redirect users to the login page. But the user is able to go "back" to the protected page, and still use the nav menu to go to another protected link and it would STILL load that page (and not redirect to login page like it should.) The only simple solution I found is to disable csr. With this solution, the user could go back, but clicking a link to protected route would correctly redirect to login page.
Fantastic video! I first watched your "don't protected with layouts", and then watched this... You helped me understand a ton about the page building process, and where to intercept the authentication checks. I really appreciate it. One question, if you put all of your protected content under a "(app)" folder using parenthesis, how should we update the event.url.pathnamne.startsWith function? (around 13:55 in). How to apply the hook to every page within a group?
Thanks a lot
You're very welcome!
I think SvelteKit should provide a better way to deal with this with something like Angular guards, for example.
Nice tutorial. I've got an off topic question though: Which vs code icons are those?
Material Icons, however, I have modified the directories underneath of routes to be green :)
Nice video
Thank you!
Hey,
I'm just starting to learn Svelte, or really making webapps in general, and just want to thank you for your awesome content so far, that I was able to discover yesterday and today.
I noticed you did some videos on Supabase and Pocketbase, and while I really like Supabase, their selfhosted version is not as feature rich and usable as their cloud version. An interesting alternative to those two is Appwrite, wich selfhosted version gives you the same experience as their hosted one.
Would it be possible for you to make some basic tutorials about Svelte and Appwrite, like securely loggin in users, with it? I'm a bit unsure how to use handle routes together with appwrite for securing access.
Thank you again for your awesome tutorials :)
Thanks for the comment! I have explored AppWrite in the past but they didn't have solid SSR support, things may have changed though, so I will look into revisiting!
Liked and viewed . Fair trade =)
Thank you!
Thanks!
You are welcome and thank you for the generous donation!
if I have a separate backend server running, and I want to make a fetch call which passes a cookie, what do I have to do for Svelte to let me pass the cookie? I've looked at the documentation, but handleFetch doesn't seem to work for me. The backend server is on the same machine, just on a different port.
Hunter, I could be mistaken but at about 16:17 in the video, when you're demonstrating that a user with a regularusertoken would be unable to access the '/protected/admin' route, it looks like you were able to access the route with the regularusertoken. Was there something misconfigured there - I haven't been able to grab the repo and go through it yet, thank you.
I couldn't, I was stupid and for some reason had the `h1` tag on the '/protected' page say "Admin". If you look again the /protected page has a title of `Admin` and '/protected/admin' has the title of Admin Page!
@@Huntabyte ah, ok that makes sense. I appreciate the reply to clarify - thank you for the amazing content!
@@roberttmorgan You're very welcome!
If I go to the admin page using an anchor link it bypasses the hook, it only runs if there is a +page.server file inside the admin folder, however if done as a hard redirect it checks the role
might look good in theory, but if you have an API call inside +page.server.ts it then event.url.pathname will show the API url, not the current page?
hunter love your videos! Could you possibly make a video about middlewares? Im thinking of multitenant with subdomain for each tenants and I think this is doable via using a function in +layout.ts but not sure how, another option is using node/express adapter. Do you know how to do it, can you possibly cover it in a video? Thanks!
I've been looking into this a bit myself, once I get through a few others things I'm working on, I will spend a bit more time on it and probably create a video!
So how do we do if we want the handle to be run on client-side routing as well? I have some pages that are not super important to guard, but I still want to redirect if the user got logged out for some reason. Now they can still navigate in the app client side when the cookie is removed.
Thanks for this great tutorial. After I wached that video I downloaded the coding from git because "LOGOUT" doesn't worked correctly in my coding. The cookie is not deleted and still I don't know why. After I downloaded your coding from git plus installation, the issue is stile there. Do you have any advise, why the cookie is not deleted?
Not working with links thats are made with a tag in build version prerender mood. But working perfectly in dev mode. Any solution?
Great video !
But I have a problem, if I delete the cookie and navigate with the previous page button of my brownser, i can still reach protected route unitl I refresh the page manualy. This is the same problem that explain in the next video "Stop using +layout for auth", thanks
If I've understood the diagram at the start of the video correctly, can I think of the Handle hook as (similar to) middleware?
You are exactly right.
Love the content, do you have any plan of doing something similar with Firebase auth?
Possibly in the future!
Something than I found is every route than you want to protect you have to create +page.server.ts file, Are there something different to that? thank in advance
I get the above, but what happens if you have a link Href on the Layout or Nav bar, and a user click on it to go to a /protectedpage ? I'm finding the above doesn't prevent a user from doing that :S ? Am I missing something?
Edit: every protected page must have a server side function, otherwise it will bypass the hooks and be rendered as a static site page! I used a console log during testing to trigger this 👌🏾 works!
Great video, thanks for putting it (and others) together. One thing I don't understand though, it seems that your protected route requires protected/+page.server.ts to exist (even if empty) in order for the handler hook to fire from a link. If you remove protected/+page.server.ts you will see that the hook is not run unless you manually navigate to it by typing in the URL (e.g. localhost:/protected). Is Sveltekit intended to work this way? Seems like a variation of the naive layout issue you referenced elsewhere in comments that could lead to dangerous consequences if you somehow forget to put an empty +page.server.ts file there.
I believe it is intended to work that way, as having a +page.server tells SvelteKit there’s something needed from the server to load that page (even if it’s empty). There are open discussions on GitHub about this and the idea of making protecting routes more obvious, something like a +auth.server. Hopefully the maintainers can make a decision and move quickly, as there are many outstanding ‘gotchas’.
@@Huntabyte Not sure if there is something for this yet. but so far I really dont like doing protected routes in sveltekit, it feels very janky / an afterthought compared to more established frameworks. Having to remember to put an empty +page.server.js in order to protect each individual route kinda makes the hook feel almost as janky as the layout.server.js, additionally at least with the layout.server.js It is nested which routes are protected, while I have to specify each route for the hooks solution. Both are kinda just trash tbh.
@@Huntabyte could the same need for +page.server be done at the root of that path with a +layout.server.js to ensure that hooks.server is run? In some initial testing I put a a +layout.server at /my, and when navigating to /my/info/profiles or /my/info, hooks.server did fire. I am not sure if this is foolproof or not and am wondering what others think of the approach.
@@brettski-tc After some testing, i also found this to work, but would be nice to have this a confirmed method from more rutined people
Hey, uhm, I don't know if I'm doing something wrong, because uh... it works for the most part, except that the client-side router may still execute the load function of a protected route when it's preloading that protected route as a response to the user hovering over a link that points towards a protected route. So I still get a console log in my browser that basically says "fetching sensitive data". It seems like in that scenario, the hook on the server is not being invoked. Do you have any tips for that? Or do I just have to disable preloading?
So is all this necessary if you're using firebase or something similar?
Thank you for a great video! Can you please tell me if event.locals object is different for every user? So i dont get leaks between different users' sessions? Sorry for a perhaps dumb question but i'm just starting... Thanks again!
It is not only unique to each user, but unique to each request even from the same user. Locals is created and only lives for the duration of each request!
@@Huntabyte Thank you!
So handle is just a service worker for Svelte, right?
please make some clone tutorials using sveltekit. Thanks in advance.
Just implemented some authentication thanks to this video. But what would be the best practise to save cookies into local storage to access the user info globally? For example, I have a Navigation.svelte component in the root +layout.svelte (where i want to display the user email) but I don't want to have every page request on the server side. But since the auth.js, hooks.server.js, and registration are done on the serverside, where should I save the cookies to the local storage? Should I have some condition in the root layout.svelte component when the cookie is set? Or should I just access the cookie in the .svelte files directly?
Thanks for any help :)
You could run a single load function on your root +layout.ts and return the users information, then within your components, use $page.data.user.email.
At 13:30, you demonstrate protected an entire path with hooks.server.ts. Then you say, "you're still going to want to ensure users aren't trying to create items for other users and things like that . . . ." Can you elaborate on what you're referring to? Are you referring to row-level security on the database side, or to some other checks?
Also, I'd love a tutorial tying together SvelteKit protected routes and Supabase authentication.
I find this easier to do by just moving whatever routes in to a route group like `(unauthenticated)` and `(app)` then making a `+layout.server.ts` that does the check of user is logged in or user role etc and doing the redirect there. That way you can apply to all the routes w/out relying on hardcoded route strings and having to prepend a path like `/protected` to it.
Layout load only runs when the first route of that layout loads. So you aren’t actually checking auth status with every request to a protected resource, only the first protected resource. There’s actually an issue open right now on this exact issue: github.com/sveltejs/kit/issues/6315
@@Huntabyte interesting… so when you enter /(protected)/something-else the layout in (protected) will not run?
I wasn't able to achieve that to be honest, but maybe it's a good opportunity to make a video about it, as some people may rely on layout.server
Put a console log inside your layout load. Navigate to /protected then click a link in your app that takes you to /protected/item. If you directly navigate through the URL, that will trigger the layout load to rerun, however, if you navigate through your app (through a link or nav menu), the layout load will not rerun unless you exit that layout tree and re-enter it. I had to investigate this quite a bit, but when I found the gaping hole in my security I've been advocating against that way of doing things. It's on the SvelteKit post-1.0 roadmap to be addressed, so I'm interested to see how they handle it. I will create a video on this most likely.
hook only run which route have +page.server.ts file if you navigate any route inside produced path without have +page.server.ts using button it will navigate because hooks.server.ts not run
I got an empty object when console logging... after 20min I found out it was because I named the hook file `hook.server.ts` and not `hooks.server.ts` ......................
why do we need cookies then, if everything can be stored in locals?
Locals read from the cookies!
hi, great video and it is really helping me in my project.
But a quick question, is it secure doing it this way? I mean we are using cookies to handle authentication and I just managed to land on the admin page by just changing the value of the cookie in my browser (with a cookie editor) from "regularusertoken" to "adminusertoken". Just like that I was able to land on to the admin page.
I have heared about cookie steaaling and such but I wanted to ask if the case I am describing is the same as cookie stealing or is the issue with the way we are handling the request? Because in the current scenario any user can just log in to our site as admin without much trouble at all.
Thanks
Also can you please guide as to what can be done to prevent this? Thank you
I think that you would use JWT tokens stored in httpOnly cookies to prevent this.
There seems to be a bypass to this method if you have a link from an unprotected route to a "protected" route
Oh this went away when I added a +page.server.ts to the route, so it seems anything server side triggers the hooks, which is fine
wouldn't this just clutter your handle hook? you'd be mixing permission checks along with user auth and probably some more stuff in one hook. wouldn't it be better to just check for permissions on each subsequent route with pageserverload? of course the benefit of handling all of it in the server hook would be that you have it one place but other than that i see no real advantage of this over checking it in the load function of each page. i may be wrong though and if i am, please do tell.
I typically do check in each page server load, however, for a massive group of routes like '/admin' where everything has auth requirements, this is an easy way to handle it.
@@Huntabyte ah i see. since there can be a lot of nested routes you may want to group them in the handle hook. gotcha. great sveltekit content btw, keep it up!
Standard of explain
Wait, is this the best solution that we have? This is terrible, basically we disable CSR, so every request goes back to the server in order to check the secure cookie... There's got to be a better way..
BTW do we even care if the user deletes their token? We have to revoke it server side anyway. Am I missing something here?
So is this the ultimate fool proof way?
For summaries/groups of routes, yes. To be extra safe, you can always check on each +page.server and action as well.
Are you using @rometools ? Curious how it is working with SvelteKit
How can I protect layouts too? I created +layout.server.ts and I put the same code but it does not work
I get the following Error: Error: Parse failure: Identifier 'Handle' has already been declared (3:11)
I´m at 5:09 in the Video and my Code in the hooks.server.js is:
import {Handle} from "@sveltejs/kit"
export const Handle = async ({event, resolve}) =>{
const response = await resolve(event)
return response
}
Does anyone know what i´m doing wrong?
If you’re not using typescript you don’t import ‘Handle’. Just do: export const handle = …
@@Huntabyte ist that also for the next step in the +page.server.js?
Because I get this error :
Error: Invalid export 'PageServerLoad' in src/routes/+page.server.js (valid exports are load, prerender, csr, ssr, actions, trailingSlash, config, or anything with a '_' prefix)
My Code:
export const PageServerLoad = async ({locals}) => {
console.log(locals);
}