代码之家  ›  专栏  ›  技术社区  ›  synergetic

SvelteKit SPA:如果用户未以原始路径作为查询参数登录,则重定向到登录页面

  •  0
  • synergetic  · 技术社区  · 2 年前

    让我们考虑以下场景。

    我有一个多租户Svltekit SPA应用程序(后端是ASP.NET)。当用户邀请另一个用户加入他/她的租户时,会向受邀用户发送电子邮件。当受邀用户单击电子邮件中的链接时,SPA应用程序会加载,并检查用户是否已登录。如果没有,则原始导航(比如“/user/acceptInvitation”)为 取消 ,被邀请的用户被重定向到登录页面,原始路径作为查询参数(“/user/login?returnUrl=/user/acceptInvitation”)。

    我试过了 beforeNavigate 在根中 +布局.svelte ,但看起来像 登机前 当应用程序首次加载时不会触发(可能是因为它只处理客户端导航,而当SPA应用程序首次装载时,它是服务器渲染的)。

    我还希望上述逻辑在另一种情况下发挥作用:如果用户通过完全浏览器页面刷新重新加载应用程序。应用程序应该从服务器请求登录的用户信息,如果有任何问题,它应该重定向到登录页面。

    0 回复  |  直到 2 年前
        1
  •  0
  •   Thomas Hennes    2 年前

    这不是您想要在客户端实现的。

    假设登录状态是通过被邀请用户的机器上是否存在会话cookie来跟踪的,那么您将希望使用服务器端中间件进行邀请路由,其逻辑如下:

    • 如果请求携带有效的会话cookie,则用户将登录并按照请求处理邀请
    • 否则重定向到以原始请求作为 returnUrl 参数

    显然,您的登录实现还应该执行重定向到 returnUrl 成功登录后,或者默认重定向到您选择的页面(如果该参数不存在)。

    因为这是在服务器端处理的,所以这也将在您的全浏览器刷新场景中发挥作用。

        2
  •  0
  •   synergetic    2 年前

    经过一番尝试,我在root中想出了以下代码 +layout.svelte :

    <script lang="ts">
        import { page } from '$app/stores';
        import { goto } from '$app/navigation';
        import http from "utilities/http";
        import User from "./User";
        import { currentUser, selectTenant } from "./appModel";
        ...
    
        let initialized = false;
    
        const url = $page.url;
        if (/* logged-in user required for the url */)
            http.get("/api/user/info")
            .then(async (res) => {
                if (res.ok) {
                    currentUser.set(User.create(await res.json()));
                    selectTenant("last");
                }
                else {
                    const returnUrl = `${url.pathname}${url.search}`;
    
                    // Await goto, otherwise 'returnlUrl' component
                    // (or root page) may start mounting! 
                    if (returnUrl !== "/") {
                        await goto(`/user/login?returnUrl=${returnUrl}`);
                    }
                    else {
                        await goto("/user/login");
                    }
                }
                initialized = true;
            });
        }
        else {
            initialized = true;
        }
    
        ...
    
    </script>
    
    {#if initialized}
    {#if $currentUser}
        <Navbar ... />
        <StatusBar ... />
        <slot />
    {:else}
         <StatusBar ... />
         <slot />
    {/if}
    {/if}