Clear login session after logging out in angularjs - angularjs

I am trying to clear login session using AngularJS code.
$scope.clearLogin = function () {
delete $window.sessionStorage;
window.localStorage.clear();
$window.location.href = 'index.html';
};
This is redirecting me to index page but when I click on back button I am getting into the application and the session is still available.
How to clear session restricting the user to log into the application after logging out?

It should be $window
$scope.clearLogin = function () {
delete $window.sessionStorage;
$window.localStorage.clear();
$window.location.href = 'index.html';
};

Related

Handling secure login page in protractor

My team is working to use AngularJs and Polymer components for a new web app. I am looking into how to create a UI automation suite for this. After lots of research looks like Protractor may help me out here with some tweaks to handle Polymer. But, the current challenge is as follows -
I navigate to the app
As part of our company policy, the every web visit is validated (unless within same session). Here is how the validation works -
A login page (non-Anugular) page appears after one types the required url. Sign in with the credentials
Another intermediate page appears where it asks to wait for page to load or click a link to go to next page. Click the link
Url changes back to the original used in #1
Note: These validation pages take hell lot of time to load (changes to different internal urls). Also, the validation is skipped sometimes (within same session or through some other logic)
I have been struggling to design a prototype to handle all these. I am also trying to use Page Object while designing the prototype. Here is what I have so far.
login.js
________________________________________________________
var currentUrl;
var lastChangedUrl;
var secureUrl = 'corplogin.ssogen2.corporate.company.com';
var getwayUrl = 'gateway.zscalertwo.net';
var loginSuite = function(driver) {
var defer = protractor.promise.defer();
describe('Handle login', function() {
/*afterEach(function() {
//driver.manage().deleteAllCookies();
})*/
//it('Login to security test', function(){
//********** Wait for page to load/URL to change to secure login page ************
driver.getCurrentUrl().then(function(url) {
currentUrl = url;
}).then(function() {
driver.wait(function() {
return driver.getCurrentUrl().then(function (url) {
lastChangedUrl = url;
return url !== currentUrl;
});
});
}).then(function() {
//********** login to secure page ************
if (lastChangedUrl.indexOf(secureUrl) > -1 || lastChangedUrl.indexOf(getwayUrl) > -1) {
var element = driver.findElement(By.name("username"));
element.sendKeys("Username");
element = driver.findElement(By.name("password"));
element.sendKeys("password"); //Give password
element = driver.findElement(By.name("submitFrm"));
element.click();
}
}).then (function() {
//********** page is slow. wait for page to load/URL to change ************
driver.getCurrentUrl().then(function(url) {
currentUrl = url;
}).then(function() {
driver.wait(function() {
return driver.getCurrentUrl().then(function (url) {
lastChangedUrl = url;
return url !== currentUrl;
});
});
}).then (function() {
//********** Click on the link to to go to test page ***********
if (lastChangedUrl.indexOf(getwayUrl) > -1) {
var element = driver.findElement(By.tagName("a"));
console.log("before click............");
element.click();
}
//********** page is slow. wait for page to load/URL to change ************
driver.getCurrentUrl().then(function(url) {
currentUrl = url;
}).then(function() {
driver.wait(function() {
return driver.getCurrentUrl().then(function (url) {
lastChangedUrl = url;
return url !== currentUrl;
});
});
})
.then (function() {
//return defer.promise;
//browser.pause();
});
}, 60000);
});
//});
}, 60000);
return defer.promise;
};
module.exports = loginSuite;
spec.js
___________________________________________________________________________
describe('Protractor Demo App', function() {
var myUrl = 'http://<my test app url>/';
var driver = browser.driver;
beforeEach(function() {
driver.get(myUrl);
});
it('should login', function() {
loginSuite(driver)
.then(
function(){
console.log("End of tests:");
expect(driver.getCurrentUrl()).toBe(myUrl);
});
});
The issue here -
My expectation here is to have the promise returns to spec.js after the secure login page is handled so that I can continue with other testing using the driver object. For the sake testing I am logging 'End of tests' message and doing a dummy validation. But, looks like those two lines don't get executed.
Login to the secure site works and I see page changes to original test page. I tested that with Browser.pause(). But, the logging 'End of test' never happens, nor the validation.
I need to handle the scenario where the secure login page doesn't appear. Not sure what adjustment I need to do in login.js page
Is my approach for page object and handling the promises wrong here? I am able to go to one step further on the test app page when all the code are placed under one js file instead of splitting them for page object. Please help here.
I wanted to share with you the "polymer way" of solving your problem.
The code below use two elements to monitor the URL, the auth flow, the previous page visited and log the user in/out of the app
The first will bind to the origin route, so you can send the user back there
<app-route
route="{{route}}"
pattern="/origin/:page"
data="{{data}}"
tail="{{subroute}}">
</app-route>
The second will bind to the authPage, allowing you to show/hide the auth page.
<app-route
route="{{subroute}}"
pattern=":authPage"
data="{{data}}
active="{{authPageActive}}">
</app-route>
User auth, monitoring and page redirecting
Use the element: <firebase-auth>
Is the user singned in?: signedIn="{{isSignedIn}}"
<firebase-auth id="auth" user="{{user}}" provider="google" on-
error="handleError" signedIn="{{isSignedIn}}"></firebase-auth>
Add an observer
observers: [
'_userSignedInStatus(isSignedIn)' // observe the user in/out
],
Add a Function
_userSignedInStatus: function (isSignedIn) {
if (isSignedIn === false) {
this.page = 'view404'; // redirect the user to another page
// import an element that cover the view
} else {
//send a log message to your database
}
}

Angular Intercepting a particular http request and prompt for login

I am working on an angular app. It's an SPA. I am loading the profile(or myAccount) page into the home page when user clicks on a link.
<a href="#" ng-click="getProfileData()"/></a>
in my controller:
$scope.getProfileData(){
$http.get('/profile').then(
function success(){
},
function error(){
}
}
}
the link makes an ajax request through $http service of angular.
what I want to do is, when user clicks on the link, before making the ajax request to check if he's logged in or not. if not, open the sign in popup, and after sign in continue with the same request.
I've looked into $httpProvider.interceptors, but I'm still not sure how to do it, since I need to pause hold the $http request till the login is completed, modify the config by adding login details into it and then continue.
Is using of interceptors the correct option? If yes, how should I proceed towards my objective?
EDIT:
my primary concern is to continue with the same request. i.e. i don't want the user to click on profile link again after he has logged in. i can check if user is logged in or not before making the ajax request. if he is, then it's good. but if he's not, he has to log in (in the modal i pop up), and then he has to click on the profile link again. is there a way to continue the previous http request after login?
There are only three points in the application where the login modal should appear:
When you are on a welcome page and you click “Login”.
When you are not logged in and you attempt to visit a page that requires login.
When you attempt to make a request that requires a login(Ex:session expiration).
Determining which pages require a logged in user
Considering you are using ui router,you can secure routes of your application with the help of attaching additional properties to a route.Here we add a requireLogin property for each state.
app.config(function ($stateProvider) {
$stateProvider
.state('welcome', {
url: '/welcome',
// ...
data: {
requireLogin: false
}
})
.state('app', {
abstract: true,
// ...
data: {
requireLogin: true // this property will apply to all children of 'app'
}
})
});
For routes that do not require a login we set requireLogin to false.
Capturing attempted state changes
This is where we are going to capture the attempted state changes and inspect them for our requireLogin property.
app.run(function ($rootScope) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
var requireLogin = toState.data.requireLogin;
if (requireLogin && typeof $rootScope.currentUser === 'undefined') {
event.preventDefault();
$rootScope.returnToState = toState.url;
// get me a login modal!
}
});
});
As you can see, if the route requires a login and $rootScope.currentUser is not yet set, we will prevent the attempted state change and show the modal.
Redirecting to initially requested url after login
The last part requires redirecting to the initially requested url after login.In our app.run we have set a variable $rootScope.returnToState = toState.url which we can use in our login controller to redirect.In our controller for the login page we can do something like this:
$scope.login = function(form) {
$scope.submitted = true;
if(form.$valid) {
Auth.login({
email: $scope.user.email,
password: $scope.user.password
})
.then( function() {
// Logged in, redirect to correct room
if( $rootScope.returnToState) {
$location.path($rootScope.returnToState);
} else {
//redirect all others after login to /rooms
$location.path('/home');
}
})
.catch( function(err) {
$scope.errors.other = err.message;
});
}
};
For further reference please refer to this blog post http://brewhouse.io/blog/2014/12/09/authentication-made-simple-in-single-page-angularjs-applications.html
This can help you build a rock solid authorization for your app which I think you might be looking for.
Why can't you just make another function call to verify, if the user is logged-in. And based on that fire up the ajax request that you are trying up there. Something like
$scope.getProfileData(){
if($scope.isLoggedin()){
$http.get('/profile').then(
function success(){
},
function error(){
}
}
}
};
$scope.isLoggedin = function(){
// Do some processing and return true/false based on if user is logged-in
};

Logout issue with site minder in angularJs

I have implemented the logout function in my application which uses site minder for login.Every time i logout for the first time its logs me out.If i login again and try to log out it directly logs in without asking credentials.
Can you help me on this. I have used $cookiestore to remove the cookies but its doesn't helps. Is there any way to get rid out of it.
Code:-
$scope.logoutUser = function() {
$cookieStore.remove('AWSELB');
$cookieStore.remove('SMSESSION');
window.location.href = config['logout_url'];
};
After calling $cookieStore.remove, try to read the value from cookie, it is still there, remove does not work properly, I already faced the same issue.
Finally I decided to use the local storage, really it is easy, better and faster
service.logout = function () {
$localStorage.loggedInUser = null;
$state.go('login');
};
On Login:
service.login = function () {
// validate and get data say user
$localStorage.loggedInUser = user;
$state.go('home');
};

Firebase logout show Permission denied error.

So whenever I logout from Firebase, I got coupled
Error: permission_denied: Client doesn't have permission to access the desired data.
I understand it is because login session is terminated, some of my objects cannot access firebase data any more. But how can I disconnect this objects before logout?
For logout button in one of my Ionic View, it just call a firebase service:
function logout() {
auth.$unauth();
getCurrentUser();
};
function getCurrentUser() {
var authData = auth.$getAuth();
if (authData) {
$rootScope.userId = authData.uid;
$rootScope.currentUser = $firebaseObject(authRef.child("users").child(authData.uid));
return $rootScope.currentUser;
} else {
console.log("User is not login!");
$rootScope.userId = null;
$location.path("/auth/signin");
if ($rootScope.currentUser) {
$rootScope.currentUser.$destroy();
}
}
};
So I destroy the $rootScope.currentUser there. I use the same getCurrentUser for profile page. So the Error did not show up this way. But when in other views, which I have another $firebaseArray, and also another Ref.on("child_added", function(snap) with the same $firebaseObject. When I view the profile page, then this page with at least 3 firebase connection, I got 3 permission_denied Errors when I logout (logout button is on user profile page).
My question is, how do I disconnect this firebase connection before I logout? Is there a way disconnect ALL the firebase connection - no matter AngularFire or regular Firebase? So I can logout without worry about which firebase connection I have no close yet? Also, since the Logout button is in Profile scope and the others connection is in a different scope, I have no idea how to close the connection which is not even in the profile scope...
You need to destroy all the firebase references on logout.
Something like this.
In logout function.
function logout() {
auth.$unauth();
$rootScope.$broadcast('logout');
};
In controller
vm.profile = authService.profile(user.uid); // FirebaseObject Reference
vm.parties = partyService.getPartiesByUser(user.uid); // FirebaseArray Reference
$rootScope.$on('logout', function () {
vm.parties.$destroy();
vm.profile.$destroy();
});
well, i guess you have a button to logout.
so in your function logout() you'd first $destroy the data object, somehow wait (whichs' best practice i'm trying to figure out), and then authref.unauth();
i'd say
You need destroy the firebase ref for the object that you saved data previously. How?
Before, I initialize my var songs like:
this.songs = this.af.list('/songs');
When I signOut(), I should destroy the reference of the variable that I initialized so that I execute:
this.songs.$ref.off();
With this line, your problem

How do I delete the cookies after signout of a User

In my app I have local sign-in and Google+ sign-in. Suppose if I login with the Google+ and after I click on the signout it works perfectly. But afterwards, if I need to login with a new User it is directly logging in with previous login without asking for login. For this reason I want to delete my cookies.
The corresponding code is given below...
this is my HTML file:
<a ng-click="signout()">Signout</a>
Controller.js:
$scope.signout = function () {
$http.get('/auth/signout').success(function(response){
console.log("nothing" + JSON.stringify(response));
var wind = window.user;
$cookies.wind = '';
console.log("windows" + JSON.stringify(wind));
$cookieStore.remove('wind');
//delete $cookies["wind"];
$location.path('/');
});
};
Where window.user is where the cookie data will be storing.
server.js:
exports.signout = function (req, res) {
req.logout();
res.status(200).send("logged out");
// res.redirect('/');
console.log('server side signout function called');
};
I tried $cookieStore.remove('wind'); and delete $cookies["wind"];
But both are not working, Please tell me of other methods to solve this (and any solutions to this problem)
This question is more networking question likely. You can't delete cookies. What you can do is only set the expired date of cookies to past.
document.cookie = mycookiename + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
Then, browser will detect either the cookies is validate or not by checking expired date.
Important
So far, version 1.3.6, there is no way to settings cookies expired date with ngCookies prepared by AngularJS. I will recommend you to using open source instead of using ngCookies. Here's the one I am using.
https://github.com/ivpusic/angular-cookie

Resources