I'm new to Angularjs, I trying to implement the Facebook login through my Angularjs app. I was successful in implementing it. :)
What I'm doing is, if the login successful I'm setting a variable logged to true.
//loading the file
$scope.logged = false;
Facebook.getLoginStatus(function(response) {
if (response.status == 'connected') {
$scope.logged = true;
//do some stuff
}
else
$scope.login();
});
But my problem is, if the user refresh the page, the $scope.logged variable becomes false again and user is asked to re-login.
I'm using a REST API (Rails) as the back end
How can I avoid these kind of situations with Angular?
Put logged_in = true to cookieStore in your login method after authentication as below.
$cookieStore.put('logged_in',true);
$rootScope.logged_in = true;
and in your Controller, do
$rootScope.logged_in = $cookieStore.get('logged_in');
Now you can use this logged_in variable anywhere in the UI to check if the user is logged in. Make sure to use 'ngCookies' module in your app. and pass the $cookieStore dependency to your controller. You can even keep the user object itself similar to logged_in variable in cookies and retrieve it from cookies. Make sure to do logged_in = false and clear other variables in cookies and set it to blank in your logout method.
Related
I am using ngStorage for storing data in local storage. I am facing this weird issue where, when I am deleting the localstorage from the browser, my website's user doesn't get logged out on url change.
Here's the code that keeps the check whether the localstorage exists or not and then does the appropriate route:
$rootScope.$on('$locationChangeStart', function (event, next, current) {
//it always by passes this
if (!$localStorage.currentUser) {
$location.path('/login');
}
});
Only when I refresh the page, it automatically routes to the login page, or else it continues to go on any route in the website and that too without having the localstorage value.
Why's this happening ? please help me
Try this
//Checks if currentUser property still exists
if (!$localStorage.hasOwnProperty("currentUser")) {
$location.path('/login');
}
I have some variables in angular controller. I have there if user is logged in and other details . When i am refreshing my page using f5 all my variables are reloading and i am getting in log in page, but before refresh i was already logged in and my variable isUserLoggedIn was true but after refresh it is false , false is this variables default value, I am declaring it in Controller .How can I save all my variables ( current point of angular controller ) and continue with my saved point after refresh ?
You can use the browsers local storage(HTML5) and store your data.
E.g:
to write:
$window.localStorage['sample-key'] = 'sample-data;
to read:
var data = $window.localStorage['sample-key']
There are many libraries available for this, you can check this one:
https://github.com/grevory/angular-local-storage
I am using filters (of web.xml) to check if the session (http session on server side) is valid or not. If the session is not valid, then the response return error 401, and I handle it in angularjs and redirect the route to login page.
So, the situation is like this:
There is a url localhost:8585/xyz. To access this url, login is required.
When the request is made to access this url (without logging in), the filter check whether the session is valid or not. Meanwhile (as the session is being checked), the template of url localhost:8585/xyz is displayed. As the user is not logged in, session is not valid, so filter send 401 error. I handle the error in angularjs and redirect the route to login page.
I don`t want the template to be displayed before getting the actual response from filters and redirecting the route to login page.
When you're defining your routes you can use the resolve property on your route (https://docs.angularjs.org/api/ngRoute/provider/$routeProvider).
This will allow you to specify a function which returns a promise and the route will only be changed once the promise resolves. As an added bonus the value coming back from the resolve promise can be injected into the handling controller.
Here is a plnkr showing how you can use a global function for any of the routes you need.
You can use ng-cloak to hide flash of unstyled content for Angular if need be.
Your main problem seems to happen after Angular is already loaded, though. In the controller that displays the template you can have a setting:
this.loaded = false;
Then in the template itself something like:
<throbber ng-if=!ctrl.loaded/>
<content ng-if=ctrl.loaded>
<!-- template content -->
</content>
Then you can set this.loaded = true when you get the response from the filter. If you get a 401 the redirect happens anyway and this.loaded doesn't get set to true anyway.
Without any example code, it's difficult to know this is possible for you, but the ng-show directive can be used to hide an element if it's provided value is falsy:
<div ng-show="authenticated">
<!-- content you wish to hide here -->
</div>
In your controller, simply set the value to true when the (successful) response is returned
myApp.controller('MyController', function ($scope) {
$scope.init = function() {
// check auth here
$scope.authenticated = true;
}
$scope.init();
});
I am trying to implement a single page application that starts with a login form. For front-end I'm using AngularJS.
In the login's controller I check the authentication data, and if it is ok, I set a cookie (using $cookieStore service) with some user data and route to another view. Here, in the controller of the second view I check if the user from the cookie is empty and if yes, I redirect to the login view.
What I want to do is when the user close the browser, or if leaves the page the cookie to be removed.
I have tried to use:
$scope.$on("$locationChangeStart", function(){
$cookieStore.remove('user');
});
or
$scope.$on("$destroy", function(){
$cookieStore.remove('user');
});
but it does not work.
I want to avoid the scenario when a user log in (the cookie is set) and is redirected successfully to the second view, and after this close the browser/leaves the page (the cookie is still there). Another user write the url of the second view and because the cookie with the data of the first user is still there, he succeed to authenticate.
Can anyone help me with this?
plunker link
I am not sure. But maybe the browser closes before you even do anything in your logic.
Try this :
$scope.$on("$locationChangeStart", function(event){
event.preventDefault()
$cookieStore.remove('user');
});
try this code, it will works
$scope.$on('$locationChangeStart',function(event) {
if($scope.formsubmitted && $scope.myForm.$dirty){
var answer = confirm("Are you sure you want to leave this page?")
if (!answer) {
event.preventDefault();
}else{
$cookieStore.remove('user');
}
}
});
I have stumbled upon Restangular for making calls to a rest service. It works great and returns a promise. I need to be able to have the call block. The reason for this is on a fresh page reload I am technically not loggged in but I may have a token stored in a cookie. i would like to validate this token against a rest service. Problem is that I need it to block.
If a timeout occurs or if its not valid that i can treat teh user as not authenticated.
This is the reason for wanting to block is that i would like to redirect them using $location.path to a new URL it not a valid token.
This doesn't happen on a specific route so i can't use resolve which is blocking. It technically happens on every route - I use the $on.$routeChangeStart and check an internal variable got LoggedIn or not, if not logged in i check for the stored token.
This happens on each Page refresh but not while navigating inside the application.
The affect I am trying to get is how Gmail works.
Look forward to any insight anyone has on this
Thanks
Basically you need to ensure that some asynchronous action occurs prior to any route change occurring, and in this case the action is authenticating a user.
What you can do is use the $routeChangeStart event that's emitted in order to add a property to the resolve object on the route like so:
function authenticate() {
if ( user.isAuthenticated ) {
return;
}
// Just fake it, but in a real app this might be an ajax call or something
return $timeout(function() {
user.isAuthenticated = true;
}, 3000);
}
$rootScope.$on( "$routeChangeStart", function( e, next ) {
console.log( "$routeChangeStart" );
next.resolve = angular.extend( next.resolve || {}, {
__authenticating__: authenticate
});
});
Since angular will wait for any promises in the resolve object to be fulfilled before proceeding, you can just use a pseudo dependency as in the example. Using something like that, you should be able to guarantee that your user is authenticating prior to any routes successfully executing.
Example: http://jsfiddle.net/hLddM/
I think the best way to do this might be to push the user around with $location.path, You can use .then() to effectively force a wait by leaving the user on a loading page.
var currentPath = $location.path();
$location.path(loadingScreen);
//Assuming you have some sort of login function for ease.
Restangular.login(token).then(
function(result) {
$location.path(currentPath)
},
function(error) {
$location.path(logInScreen)
}
);
If you're using ui-router, you could move to another state with the same URL, where you'd use that Restangular.login with the then, and in case of success go back to the "logged in" state, otherwise, go to the "log in" state where the user must enter his username and password.
If you're not using ui-router, you could implement something like that with some ng-switch.
So, upon arrival to the screen, you do that Restangular.login and by default you show loading page by setting some boolean to true. Then, if it doesn't succedd, you send him to the login, otherwise, you set loading to false and show page.
Anyway, I'd strongly recommend using ui-router, it rocks :)
Hope this works!