jeudi 26 janvier 2017

Fixing custom authenticator's restore method

I'm using ember-simple-auth and a custom authenticator for an HTTP basic login with CSRF protection. Everything is working fine except sometimes my restore method resolves when it should be failing, like when the session expires.

When authentication succeeds I resolve with the csrf token, but then when the token or session expires and I refresh the page, the resolve method succeeds because all I'm doing is checking if the token is still there (not if it's valid). I know this is wrong, so I guess my question would be what is the proper way to handle this? Should I also be resolving with the session id? Should I be sending an AJAX request in the restore method with the stored token to see if it is still valid and returns success?

Here is my authenticator code:

import Ember from 'ember';
import ENV from 'criteria-manager/config/environment';
import Base from 'ember-simple-auth/authenticators/base';

export default Base.extend({

    restore(data) {
        return new Ember.RSVP.Promise((resolve, reject) => {
            if (data.token) {
                Ember.$.ajaxSetup({
                    headers: {
                        'X-XSRF-TOKEN': data.token
                    }
                });
                resolve(data);
            }
            else {
                reject();
            }
        });
    },
    authenticate(credentials) {
        let csrfToken = this.getCookie('XSRF-TOKEN');
        return new Ember.RSVP.Promise((resolve, reject) => {
            Ember.$.ajax({
                beforeSend: function(xhr) {
                    xhr.setRequestHeader("Authorization", "Basic " + btoa(credentials.username + ":" + credentials.password));
                    xhr.setRequestHeader("X-XSRF-TOKEN", csrfToken);
                },
                url: ENV.host + "/api/users/login",
                method: 'POST'
            }).done(() => {
                //A new CSRF token is issued after login, add it to future AJAX requests
                Ember.$.ajaxSetup({
                    headers: {
                        'X-XSRF-TOKEN': this.getCookie('XSRF-TOKEN')
                    }
                });
                Ember.run(() => {
                    resolve({
                        token: this.getCookie('XSRF-TOKEN')
                    });
                });
            }).fail((xhr) => {
                Ember.run(() => {
                    if(xhr.status === 0) {
                        reject("Please check your internet connection!");
                    }
                    else if (xhr.status === 401) {
                        reject("Invalid username and/or password.");
                    }
                    else {
                        reject("Error: Http Status Code " + xhr.status);
                    }
                });
            });
        });
    },
    invalidate() {
        return new Ember.RSVP.Promise((resolve, reject) => {
            let csrfToken = this.getCookie('XSRF-TOKEN');
            Ember.$.ajax({
                beforeSend: function(xhr) {
                    xhr.setRequestHeader("X-XSRF-TOKEN", csrfToken);
                },
                url: ENV.host + '/logout',
                method: 'POST'
            }).done(() => {
                Ember.run(() => {
                    resolve();
                });
            }).fail(() => {
                Ember.run(() => {
                    reject();
                });
            });
        });
    },
    getCookie(name) {
        let alLCookies = "; " + document.cookie;
        let cookieArray = alLCookies.split("; " + name + "=");
        if (cookieArray.length === 2) {
            return cookieArray.pop().split(";").shift();
        }
    }
});




Aucun commentaire:

Enregistrer un commentaire