Sapper event for route change
Asked Answered
B

2

9

I need to redirect users to login page if they are not authenticated. I need something like route.beforeEach in Vue.js, ideally:

sapper.beforeRouteChange((to, from, next) => {

  const isAuth = "[some session or token check]";

  if (!isAuth) {
    next('/login')
  }

  next()
})

I found Sapper - protected routes (route guard) this question but I think it's not enough for my needs. What if token or auth changes in runtime? OR is it covered by reactivity?

Edit 1: I think that this issue on Sapper GitHub solves my problem.

Bernadettebernadina answered 4/11, 2019 at 10:15 Comment(0)
B
12

So I placed this code to /src/routes/_layout.svelte:

  import AuthMiddleware from "../methods/authMiddleware.js";
  import { goto, stores } from '@sapper/app';
  const { page } = stores();

  if (typeof window !== "undefined" && typeof document !== "undefined") {
    page.subscribe(({ path, params, query }) => {
      const from = window.location.pathname;
      const redirect = (href) => { goto(href); }

      AuthMiddleware.beforeChange(from, path, redirect, params, query);
    })
  }

And this is authMiddleware.js file:

export default class AuthMiddleware {

  static beforeChange(from, to, redirect, params, query) {

    if (!AuthMiddleware._isUserAuthenticated()) {
      redirect("/login");
    }
  }

  // ~

  static _isUserAuthenticated() {
    return true; // TODO: Implement
  }
}

more information on route hooks can be found here

Bernadettebernadina answered 4/11, 2019 at 12:7 Comment(3)
How I can redirect specific pages here? like profile page if lot login redirect to login page.Bonspiel
I like this solution but how is AuthMiddleware.beforeChange() executed before the route change? In my experimentation any callback passed into subscribe is called after the store changes. Further, I've found from and to are equal because the route change has already happened by the time the function is executed. I'm only asking because I'm curious what you did beyond whats included in the answer.Anesthetic
Yeah sorry. It is possible that beforeChange is not really called before the route change (It was just some good sounding name that I liked). I just needed SOME solution for my problem and at that time this was enough for my needs. If you find something better, feel free to edit my answer (or send me an DM and I will edit it myself).Sough
W
-1

You can also use authenticationMiddleware.js inside server.js file

Here is authenticationMiddleware.js file

import { get, post } from "./../lib/api";
async function authenticationMiddleware(req, res, next) {
    let user = null
    const cookies = require('cookie-universal')(req, res);
    if (cookies.get('token')) {
        try {
            user = await get("users/me", null, cookies.get('token'));
        } catch (e) {
            console.log('err at users', e.toString());
        }
        req.user = user
        req.token = cookies.get('token')
    } else {
        req.user = {}
        req.token = null
        cookies.set('token', null)
    }
    next();
}
export { authenticationMiddleware }

e.g. https://github.com/itswadesh/sapper-ecommerce/blob/master/src/server.js

Whitehorse answered 21/4, 2020 at 4:21 Comment(2)
Would this work on exported static version ot the app?Sough
I think the issue you're going to run into here is that sapper is a little bit too efficient. Once you get the main chunks over to the client calls for rendered components happen infrequently. From what I can tell, beyonk-adventures/sapper-rbac has the most complete solution to date but they still need that client-side part.Recrement

© 2022 - 2024 — McMap. All rights reserved.