6

I have read other postings that discuss ways that other technologies clean up the browser cookies when the browser is closed down, but none of them show how to get AngularJS to do this. How do I trigger a cookie removal method in AngularJS to run when the browser is closed?

In AngularJS 1.4.8, cookies can be removed with the syntax $cookies.remove('keyname'). I can write a method to remove all the cookies by name. But how do I make sure that the cookie removal method is called whenever the browser is closed? Is the syntax any different if I want the method to be called when a browser tab is closed?


ONGOING EFFORTS:


As per @User2341963's suggestion, I added cookie removal code to the run method in the main module of the app. The same exact code runs correctly when I put it in a logout() method elsewhere in the app, but when I put breakpoints in the firefox debugger and close the browser, I see that the cookie removal code is never run when the browser is closed. What specific changes do I make to the code to get the cookies to all be removed by AngularJS when the browser is closed?

Here is the code for the main module of the app, including the run() method:

angular
    .module('hello', [ 'ngRoute', 'auth', 'home', 'secure', 'public1', 'navigation' ])
    .config(

            function($routeProvider, $httpProvider, $locationProvider) {

                $locationProvider.html5Mode(true);

                $routeProvider
                .when('/', {
                    templateUrl : 'js/home/home.html',
                    controller : 'home'
                })//plus other routes
                .otherwise('/');

                $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

            }
    ).run(['$cookies', '$window', '$log', function($cookies, auth, $window, $log) {

        //other stuff

        $window.onbeforeunload = function() {
            // Clearing all cookies now!
            $cookies.remove("AUTH1"); 
            $cookies.remove("AUTH2");
            $cookies.remove('procStep');
            $cookies.remove('usrname');
            $cookies.remove('exists');
            $cookies.remove('wid');
        };
    }]);
CodeMed
  • 9,527
  • 70
  • 212
  • 364
  • maybe something like [how to trigger a function on window close using angularjs](http://stackoverflow.com/questions/30345446/how-to-trigger-a-function-on-window-close-using-angularjs)? Basically setup the window.onbeforeunload function – logee Feb 10 '16 at 01:34
  • 2
    use session cookies. No worry about clean up – charlietfl Feb 10 '16 at 01:35
  • @user2341963 Which controller do I put that in? The app has many controllers. The main module for the app only has `module()`, `.config()` and `.run(){}` in it. – CodeMed Feb 10 '16 at 01:42
  • I'd put it in the `run`, something like [this](http://plnkr.co/edit/enwAuA09CBsYZNjBTyIN?p=preview). Or you could try session cookies as charlietfl as suggested – logee Feb 10 '16 at 01:50
  • @user2341963 I added code to the end of the OP showing how I tried to implement your suggestion, and explaining that the debugger showed that the new cookie clearing method is not being called when the browser closes. What else can I try? – CodeMed Feb 10 '16 at 02:43
  • @charlietfl Thank you. I know you are not a Spring person, but changing all the `response.setCookie()` lines in the backend REST controller to `session.setAttribute()` lines for the same key value pairs did not produce anything that the AngularJS client app could read using `$cookies.get('keyname')` even though they were the same key names. I know you are a client side person, but do you have other suggestions? I updated my OP with the results of trying the other user's suggestion. – CodeMed Feb 10 '16 at 02:46
  • if any of those cookies are `httpOnly` cookies you can't access them in javascript...they are protected. – charlietfl Feb 10 '16 at 02:49
  • @charlietfl The cookies in the original situation in the OP can all be destroyed in AngularJS using `$cookies.remove('keyname');` The problem is that the code I added above is not being run when the user closes the browser. Simply figuring out how to get the method to run when the browser is closed would be huge, especially if it worked in all browsers. – CodeMed Feb 10 '16 at 03:14
  • Anything you try to do in beforeunload is not foolproof. If power goes out for example. Why is it so important to get rid of the cookies and why aren't you setting session cookies in javascript if you have to remove them? Or set non httpOnly cookies at server – charlietfl Feb 10 '16 at 03:27
  • In other words ...what higher level problem are you trying to solve? – charlietfl Feb 10 '16 at 03:29
  • @charlietfl This is a multi-factor authentication problem. The user gets specific views based on their progress through the multi-step authentication process. Right now, a user can close their browser mid-process and then someone else can open a new browser go to the same site, and see all the person's stuff. I would like for the person to be logged out when they close the browser. I could use javascript to set cookies, but I am receiving cookies from the backend REST authentication, and dont want to make it unnecessarily complex. – CodeMed Feb 10 '16 at 04:16
  • @charlietfl Could we deal with the power outage scenario by also running the logout/clear-cookies method when a new browser window is opened? In this case, we would want to keep the person logged in if just a new tab is opened, but log them out if a whole new browser instance is opened. Log them out of the client app, which is separate from the server app. Would this close the hole you mention? – CodeMed Feb 10 '16 at 10:29
  • @CodeMod Why are you nesting so many describe's inside of each other? A test spec file should really just be a "describe full of it's", and only make describe's if you need more beforeEach blocks. – Jim May 13 '16 at 16:27
  • @Jim The code I posted was just for the main `.js` file in the Angular app, which includes the `hello` `module` definition, along with its `config()` and `run()`. So I do not understand your comment. – CodeMed May 13 '16 at 16:36

1 Answers1

1

If you need only cookies, because you need it to be sent to backend server, you can use the main controller's $destroy event.

Using $on.$destroy

This event called when the controller about to be destroyed.

Other option is to use angularjs sessionStorage

Session Storage removed when the window is closed automatically

Itamar
  • 1,601
  • 1
  • 10
  • 23
  • I cannot validate your answer because I am on to something else now. But thank you and+1 for trying to help others with this old question. Someone else please validate this and post a comment stating validation. – CodeMed May 20 '17 at 22:04