Как проверить, что пользователь все еще вошел в систему при получении уведомления pu sh? - PullRequest
0 голосов
/ 30 января 2020

Я хочу убедиться, что если пользователь выходит из системы или удаляет свои куки, он не продолжает получать уведомления pu sh (которые могут содержать личную информацию).

Я не могу просто уничтожить пу sh, когда пользователи выходят из системы, или очистка файлов cookie не помешает им войти.

Я думал, что могу установить повара ie с идентификатор пользователя, когда они вошли в систему и очистили его, когда они вышли из системы, затем отправьте его вместе с каждым pu sh и проверьте, соответствует ли он повару ie, но, очевидно, вы не можете проверить файлы cookie или другое локальное хранилище из работник службы.

Есть ли другие варианты? Конечно, это то, что нужно делать многим веб-сайтам.

Ответы [ 2 ]

0 голосов
/ 05 февраля 2020

Я закончил тем, что просто запрограммировал все, чтобы отслеживать пользовательский сеанс в сервисном работнике с использованием локального хранилища. Я публикую его здесь на тот случай, если у кого-то еще возникнет эта проблема, и он найдет мой вопрос:

Для этой реализации необходимо:

  • idb-keyval для включения в работник службы, хотя вы, вероятно, можете сделать что-то еще.
  • URL-адрес на вашем сервере, который вы можете запросить, который возвращает идентифицирующее значение для пользователя (например, идентификатор его базы данных)

В основном он выбирает идентификатор пользователя с сервера и сохраняет его (и время, когда он был сохранен). Когда вы получаете pu sh, вы можете получить самый последний идентификатор (который будет обновляться, если срок его действия истек), который затем можно сравнить с идентификатором, который вы включили в свои уведомления pu sh. Вы также можете позвонить в службу проверки, чтобы обновить последнее состояние, которое я делаю при активации, а также при загрузке / входе в систему или / выходе из системы.

вот мой код:

//paste in code from https://github.com/jakearchibald/idb-keyval/blob/master/dist/idb-keyval-iife.min.js
const USER_SESSION_EXPIRATION = 60; //minutes

//wait for push event
self.addEventListener('push', e=> {
    var data = e.data.json();

    //get currently stored session id
    verifySessionUser().then(sessionUserId => {
        if (!sessionUserId) console.log('sessionUserId not found (somehow....)');
        console.log('sessionUserId - stored:',sessionUserId,'| push:',data.data.userId,'| =',sessionUserId==data.data.userId);

        //if id passed from push matches stored ID
        if (sessionUserId != data.data.userId) return console.log('stored session ID does not match push id, not displaying push');

        //show push notifiation to user
        self.registration.showNotification(data.title, {
            body: data.body,
            icon: data.image,
            badge: '/images/badge.png',
            data: data.data,
        });

    });
});


//catche failed requests and displays the offline page when necessary
self.addEventListener('fetch', function(e) {
    e.respondWith(
        //attempt to request page from server
        fetch(e.request)
            //request was successful
            .then((response) => {

                //check if the logout url was requested
                if (e.request.url.includes('example.com/logout')) {
                    console.log('SW - user logged out, clearing saved session user');
                    idbKeyval.del('currentUserSession');
                }

                //check if the url was a login auth url (the user just logged in)
                else if (e.request.url.includes('example.com/login')) {
                    console.log('SW - user logged in, updating session user');
                    verifySessionUser();
                }

                return response;
            })
    );
});

//new service worker installed
self.addEventListener('activate', function(e) {
    console.log('SW - ACTIVATED ');

    verifySessionUser();
});

//checks for a valid current session id - updates it if not, rejects if new session is invalid
function verifySessionUser () {
    console.log('SW - verifying session user');
    return new Promise((resolve, reject) => {
        //attempt to get the current session user
        getSessionUser()
            //success - the session id is valid and up to date
            .then(userId => resolve(userId))
            //error - getting it failed, we should update it
            .catch(currentSessionStatus => {
                console.log('SW - session invalid: '+currentSessionStatus);
                updateSessionUser()
                    .then((freshSessionUserId) => resolve(freshSessionUserId))
                    .catch(err => reject(err));
            });
    });
}

//tries to get the currently stored session user; rejects if it's expired or empty
function getSessionUser () {
    console.log('SW - reading stored session user');
    return new Promise((resolve, reject) => {

        //check if the session has expired
        idbKeyval.get('lastUserSessionUpdate').then(lastUpdate=>{
            if (!lastUpdate)
                var minutesSinceLastUpdate;
            else
                var minutesSinceLastUpdate = Math.floor((new Date() - lastUpdate) / 1000 / 60);
            //console.log('minutes',minutesSinceLastUpdate,(new Date() - lastUpdate),USER_SESSION_EXPIRATION,minutesSinceLastUpdate > USER_SESSION_EXPIRATION);

            //check if session has expired
            if (minutesSinceLastUpdate >= USER_SESSION_EXPIRATION) {
                console.log('session has expired',minutesSinceLastUpdate ,'>=', USER_SESSION_EXPIRATION,minutesSinceLastUpdate >= USER_SESSION_EXPIRATION);
                return reject('expired');
            }

            //get currently stored session id
            idbKeyval.get('currentUserSession').then(sessionUserId => {
                if (!sessionUserId) return reject('empty');

                //success
                return resolve(sessionUserId);
            });

        });
    });
}

function updateSessionUser () {
    console.log('SW - updating session user');
    return new Promise((resolve, reject) => {
        //fetch session user id from server
        fetch('/user/session').then((e) => {

            //the request failed, most liked returned 404 because the user isn't logged in, so delete the saved session info if we have it
            if (!e.ok) {
                console.log('SW - session request failed',e);
                idbKeyval.del('currentUserSession');
                return reject('request failed');
            }

            //get text value of page (wow we need a whole function to do this? idiots.)
            e.text().then(text => {
                if (text.length != 24) {
                    console.log('SW - invalid session id returned',text,text.length);
                    idbKeyval.del('currentUserSession');
                    return reject('invalid length');
                }

                //success - save value to local storage
                idbKeyval.set('currentUserSession',text);
                idbKeyval.set('lastUserSessionUpdate',new Date());
                console.log('SW - updated session',text);
                return resolve(text);
            });
        });
    });
}

может быть несколько невыполненных обещаний, но только там, где их не нужно поймать.

0 голосов
/ 04 февраля 2020

Так что обслуживающий работник не может получить доступ к магазину повара ie, по крайней мере, я так не думаю. Я все равно ими не пользуюсь, так что вот что.

Вместо этого я использую токен-аутентификацию. Это надежнее и безопаснее и т. Д. c. бла-бла-бла.

Я сохраняю токены в IndexedDB, к которым у работника сервиса есть доступ. Поэтому, когда уведомление получено, вы можете проверить наличие действующего токена и отображать уведомление только тогда, когда критерии этого токена удовлетворены.

Вы также можете удалить их регистрацию pu sh в этот момент, так как это управляется в сервисном работнике. Не забудьте отправить отписку на ваш сервер, когда это произойдет.

...