• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Vue Routing Przekierowanie jeśli user nie ma uprawnień

Object Storage Arubacloud
0 głosów
156 wizyt
pytanie zadane 5 marca 2022 w JavaScript przez Pico Obywatel (1,330 p.)

Witam, mam taki problem że chciałbym przekierować usera na stronę główną jeśli nie ma on uprawnień.

router.beforeEach((to, from, next) => {
    let url = null;
    //Function to prevent multiple using of next()
    function redirect(u = null)
    {
        url = u
    }

    //Checking if user data is present in vuex. If not then get it from api
    if(store.getters.token != null)
    {
        if (store.getters.user === undefined)
        {
            axios.get('api/me')
                .then(response =>
                    {
                        if(response.data.api_status == 200)
                        {
                            store.dispatch('user_update', response.data.user)
                        }
                        else if(response.data.api_status == 401)
                        {
                            store.dispatch('logout')
                        }
                        else
                        {
                            console.log(response.data)
                        }
                    })
        }
    }


    //In these conditions i define what should be done if they're not fulfilled

    //Check if user is authenticated. If not then redirect to login page
    if (to.matched.some(record => record.meta.requiresAuth))
    {
        if(!store.getters.token)
        {
            redirect('/login')
        }
    }

    //Checking if user is guest. If not then redirect to /
    if(to.matched.some(record => record.meta.guest))
    {
        if(store.getters.token)
        {
            redirect('/')
        }
    }

    //Checking if user has permission to enter specific site. If not then redirect to /
    if(to.matched.some(record => record.meta.requiredPermissions) && url == null)
    {
        axios.get('sanctum/csrf-cookie').then(response => {
            axios.post('api/check_permissions', to.meta.requiredPermissions)
                .then(response =>
                    {
                        console.log(response.data)
                        if(!response.data)
                        {
                            redirect('/') //To nie działa

                        }
                    })
            })
    }

    //Redirecting to url specified in redirect() function or to the default direction if not encountered error
    next(url)
})

Chodzi o tego ostatniego ifa. console.log ładnie wyświetla false, czyli nie ma uprawnień, a przekierowania jednak nie ma. Ktoś wie o co może chodzić?

1 odpowiedź

0 głosów
odpowiedź 5 marca 2022 przez ScriptyChris Mędrzec (190,190 p.)

Patrząc "na oko", to problemem jest asynchroniczność. Jeśli dobrze rozumiem, to next(url) w linii 72 przekazuje docelowy stan url do kolejnego middleware. Kod od 58 do 68 linii wykonywany jest później niż kod z linii 72, stąd niedziałające przekierowanie.

Spróbuj użyć async/await. Przykład (usunąłem Twoje komentarze i dodałem swoje, żeby wyjaśnić zmiany w kodzie):

router.beforeEach(async /* oznacz funkcję jako async, aby móc użyć await */ (to, from, next) => {
    let url = null;

    function redirect(u = null)
    {
        url = u
    }
 
    //
    // reszta kodu
    //
 
    if(to.matched.some(record => record.meta.requiredPermissions) && url == null)
    {
        // poczekaj na wywołanie HTTP
        await axios.get('sanctum/csrf-cookie').then(response => {
            // zwróć promis z zagnieżdżonego zapytania HTTP
            return axios.post('api/check_permissions', to.meta.requiredPermissions)
                .then(response =>
                    {
                        console.log(response.data)
                        if(!response.data)
                        {
                            // teraz powinno zadziałać, bo całość będzie czekać na zakończenie zagnieżdżonych zawołań do axios
                            redirect('/')
                        }
                    })
            })
    }
 
    next(url);
})

Swoją drogą, funkcja redirect wydaje się zbędna, bo odpowiada tylko za nadpisanie obecnej wartości dla url.

komentarz 5 marca 2022 przez ScriptyChris Mędrzec (190,190 p.)

Na marginesie: nie znam Vue, więc nie mam pewności czy użycie async w kontekście routera zadziała bez jakichś efektów ubocznych, ale sądząc po dokumentacji, to powinno działać.

komentarz 5 marca 2022 przez Pico Obywatel (1,330 p.)

@ScriptyChris, Co do funkcji redirect to nie wiem jakie może być lepsze rozwiązanie bo jeśli w każdym ifie użyję next() to wywali error że może być tylko 1 raz użyte

komentarz 5 marca 2022 przez ScriptyChris Mędrzec (190,190 p.)

A próbowałeś wołać return next( .. ), z przekazaniem tego samego parametru jako url, zamiast wołać redirect( .. )?

komentarz 6 marca 2022 przez Pico Obywatel (1,330 p.)
Nic to nie zmienia. Dalej otrzymuję komunikat: The "next" callback was called more than once in one navigation guard when going from "/" to "/profile". It should be called exactly one time in each navigation guard. This will fail in production.

 

Ale główny problem rozwiązany więc dzięki za pomoc
komentarz 6 marca 2022 przez ScriptyChris Mędrzec (190,190 p.)
Możesz pokazać aktualny kod?
komentarz 6 marca 2022 przez Pico Obywatel (1,330 p.)
W sumie to jedyne co się zmieniło to to co podałeś więc chyba nie bardzo jest sens
1
komentarz 6 marca 2022 przez ScriptyChris Mędrzec (190,190 p.)
Pokaż, bo może coś zostało przeoczone. ;)
komentarz 6 marca 2022 przez Pico Obywatel (1,330 p.)
router.beforeEach(async (to, from, next) => {
    let url = null;
    //Function to prevent multiple using of next()
    function redirect(to = null)
    {
        url = to
    }

    //Checking if user data is present in vuex. If not then get it from api
    if(store.getters.token != null)
    {
        if (store.getters.user === undefined)
        {
            axios.get('api/me')
                .then(response =>
                    {
                        if(response.data.api_status == 200)
                        {
                            store.dispatch('user_update', response.data.user)
                        }
                        else if(response.data.api_status == 401)
                        {
                            store.dispatch('logout')
                        }
                        else
                        {
                            console.log(response.data)
                        }
                    })
        }
    }


    //In these conditions i define what should be done if they're not fulfilled

    //Check if user is authenticated. If not then redirect to login page
    if (to.matched.some(record => record.meta.requiresAuth))
    {
        if(!store.getters.token)
        {
            redirect('/login')
        }
    }

    //Checking if user is guest. If not then redirect to /
    if(to.matched.some(record => record.meta.guest))
    {
        if(store.getters.token)
        {
            redirect('/')
        }
    }

    //Checking if user has permission to enter specific site. If not then redirect to /
    if(to.matched.some(record => record.meta.requiredPermissions) && url == null)
    {
        await axios.get('sanctum/csrf-cookie').then(response => {
            return axios.post('api/check_permissions', to.meta.requiredPermissions)
                .then(response =>
                    {
                        if(!response.data)
                        {
                             redirect('/')
                             alert("Nie masz dostępu do tej strony!")
                        }
                    })
            })
    }

    //Redirecting to url specified in redirect() function or to the default direction if not encountered error
    next(url)
})

 

komentarz 6 marca 2022 przez ScriptyChris Mędrzec (190,190 p.)

Nie zamieniłeś wywołań redirect( .. ) na return next( .. ).

komentarz 6 marca 2022 przez Pico Obywatel (1,330 p.)
No bo tłumaczę że wtedy pojawiał się następujący komunikat
komentarz 6 marca 2022 przez ScriptyChris Mędrzec (190,190 p.)

Więc pokaż kod po zmianach, czy nie przeoczyłeś czegoś. Jeśli każde wywołanie next poprzedziłeś return, to błąd nie powinien się pokazać, bo będzie tylko jedno takie wywołanie w całym callbacku.

Podobne pytania

+1 głos
1 odpowiedź 212 wizyt
0 głosów
0 odpowiedzi 118 wizyt
pytanie zadane 31 października 2019 w JavaScript przez BT101 Stary wyjadacz (12,540 p.)
0 głosów
0 odpowiedzi 81 wizyt
pytanie zadane 24 lutego 2019 w JavaScript przez ShiroUmizake Nałogowiec (46,300 p.)

92,555 zapytań

141,403 odpowiedzi

319,553 komentarzy

61,939 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...