AngularJS: How to login once and do not need to login again - angularjs

I have implemented the authentication/authorization using AngularJS, Jersey REST and Spring Security. After logged in, call the following "create" method to store the user information:
.factory('Session', function () {
this.create = function (user) {
this.id = user.sessionId;
this.username = user.username;
this.userRoles = user.roles;
};
... ...
return this;
})
But, the problem is, every time I do one of the following 2 things, the stored information is lost and I have to login again:
Reload the whole page by pressing F5 or reload icon of browser
OR
Access the same URL from browser address bar
Could you please help me on how to reserve this information to guarantee login only once?
Thanks,

Check out sessionStorage. Not sure what the rest of your code looks like, but presumably your controller could save the Session created by your factory into sessionStorage.

Related

Session Handling in Angular JS, with Spring MVC

I am creating a project in AngularJs at frontend and Spring MVC in backend.
Now assume when a used logged in and if he wants to update his information, for this i have created an api which request for emailid and update the rest object in database of that email id
Now i have some questions,
1.) I dont want to use CookieStore or others sessionStorage or localstorage (because of my personal vulnerability experience and also i want to use session only) in Angular, how can i do it in angular with Spring MVC.
2.) How can i retrieve the email id from session to update data?
3.)If a user goes to another page how can i maintain that session in another page, how can i check that session is there and user is authentic to see the page
Read a lot about it but unable to find the exact solution with session. Answer over there is manage it by cookieStore.or localstorage, Please help
Let's try and see what is happening here using cookies is the right way to this, you may think it is not safe but is the safest way to do it. With cookies you will be sharing the same session in all tabs, so you can handle in all tabs and share it.
There is also an alternative option and is using URL rewriting, quoting #vanje in this question in stackoverflow
the session is only identified via a URL parameter containing the session ID. So every internal URL of your web application has to be enhanced with this parameter using the method HttpServletResponse.encodeURL(). If you are using a web framework like Wicket, chances are good that this is already done for you.
Lets go now with the Angular JS - Spring MVC approach:
There is no need to access the session within the Angular JS front-end, if you need to use it and you are using JSP you may use scriplet to retrieve the information openening a <%= session.getAttribute("user") %> , but as I said there is no need to do this. You may call your function, and retrieve this information in your controller in Spring.
You have a controller in angular JS that calls with http to your REST controller in Spring such like this. assuming that you save your user first in session:
$scope.getUserInfo= function () {
$http.get(appContextPath +'/rest/getuser/').success(function (data) {
$scope.user= data;
});
};
You may have a request mapping for the URL above:
#RequestMapping(value = "/rest/getuser", method = RequestMethod.GET)
#ResponseBody
public User getUserInfo (HttpSession session) {
User nUser = session.getAttribute("user");
return nUser;
}
I think the best way is to create a method in your AngularJS controller and then call it.
Java code:
#RequestMapping(value = "/menu/get", method = RequestMethod.GET, headers="Accept=*/*")
public #ResponseBody Empleado showMenu(HttpSession session) {
Empleado empleado = (Empleado) session.getAttribute("empleado");
return empleado;
}
AngularJS code:
angular.module('myModule')
.controller('myMenuController', ['$scope', '$http'
function($scope, $http){
getEmpleadoInfo = function () {
$http.get(myContextPage + '/menu/get')
.then(function(data) {
$scope.empleado = data;
})
}
getEmpleadoInfo();
}]);
This way, when you load the page, the object will be loaded on the scope.

Making a logged in user-variable in AngularJS+laravel

I'm trying to make a global variable called theUser which contains the userinfo if logged in.
I have tried putting this in my SPA php file:
app.value('theUser', '<?php echo Auth::user(); ?>');
And it works but only after refreshing page. (Login happens via angularjs logic + a $http request to auth/login which returns userinfo if logged in)
In my angular auth app, I have done this:
var login = $http.post("auth/login", sanitizeCredentials(credentials)).success(function(data) {
theUser = data;
$rootScope.theUser = theUser;
});
And that works, but only when the user logs in. If I refresh, theUser is empty. And I can't get these two solutions to work together. I probably need another approach.
All I want is an user variable that I can access from anywhere in my app,
which is set if the user logs in, or have been logged in before. Using Laravel 5.1.
Here is my auth app service js: http://pastebin.com/HcdLaZcD
How can I make this work?
Why dont you use PHP-Vars-To-Js-Transformer by Laracasts. Then whenever a User logs in, you could set a Session variable auth_user and then get that variable to JavaScript as shown below (in your Laravel AuthController#login):
...
\Session::put('auth_user', \Auth::user());
JavaScript::put([
'theUser' => \Session::get('auth_user')
]);
...
And when the User logs out: \Session::forget('auth_user');
theUser variable will be available anywhere in your JavaScript (or you can Namespace it also, check the Github link above).
on top of the page under script tag
window.user = <?php echo Auth::user(); ?>
and
app.value('theUser',window.user);
app.run(function ($rootScope, theUser) {
$rootScope.theUser = theUser;
});
For accessing the logged in user from your JavaScript files, you may try something like this (Create a view composer, also layouts.master dictates layouts/master.blade.php):
View::composer('layouts.master', function($view) {
$user = null;
if(Auth::check()) {
$user = Auth::user();
}
$view->with('authUser', $user);
});
In the master layout try this (So User variable will be available as JS object if the user is logged in):
<head>
<script>var User = {{ $authUser or 'undefined' }}</script>
</head>
This is just an idea, implement it according to your need. Also, you may use a namespace like App.user. I wrote an article about this lasr year, you may
check it here. Btw, it was for Laravel 4.x.
.
We have made use of html5 local storage to overcome this once the user is logged in, you just put the user's info on html5's local storage (works on all browsers, even mobile).
It has some drawbacks which you have to overcome, and also have some control on your routes filters to avoid someone loading page they shouldn't be allowed to see.
But I'm afraid my answer applies better to our solution and I don't think this answer is perfect but might guide you in a better solution. Our app publishes an API for angular's use and this angular is somewhat empowered with some extensions to ease routing.

How to make initial authenticated request with token from local storage?

I'm using vanilla flux with some utils for communicating with my APIs.
On initial page load I'd like to read some token from local storage and then make a request to my API to get my data.
I've got a LocalStorageUtils.js library for interacting with window.localStorage. My container component handles all login/logout actions and reads the current user on page load.
App.js
componentWillMount() {
LocalStorageUtils.get('user');
}
LocalStorageUtils reads the value and brings it into Flux via ServerAction similar to the flux chat example.
get(key) {
var value = window.localStorage.getItem(key);
if (value) {
ServerActionCreators.receiveFromLocalStorage(key, value);
}
}
That puts the user into my UserStore and into my views where I can show the username and some logout link, etc.
I also have ApiUtils.js for requesting data from the server. So the question is: Where do I tell my ApiUtils that I have a logged-in user at initial page load?
I could call some method inside ApiUtils from my LocalStorageUtils but that does not feel right.
Or do I have to make another round trip whenever I get a change event inside my container component?
You should pass the user as data to your ApiUtils class and removing the need from being concerned about how your ApiUtils is used.
var ApiUtils = function () {
this.get = function (endpoint, data) {
return theWayYouSendAjaxRequests.get(endpoint).setData(data);
};
};
// Wherever your ApiUtils is used.
var api = new ApiUtils();
api.get('/me', {user: userFromStore});
I found a solution that works and feels right.
As getting data from local storage is synchronous there is no need to pipe it through Flux via ServerActionCreators. Simply use LocalStorageUtils to get the current user and call the login method with that user. The login Action is the same you would use when a user initially logs in. login triggers getting new data from server. The new data is saved in my DataStore and the user is saved to my UserStore.
Thanks for all hints at Twitter and at https://reactiflux.slack.com/.

How do I handle Token Authentication with AngularJS and Restangular?

I have an angular app that uses Restangular and ui.router.state.
This is what I am currently doing
I have an Endpoint /Token that accepts a username/pass and gives
back a bearer token and some user info.
On successful login I save off the userinfo and token into a global var, user.current and I also set Restangular's default headers to include the bearer token:
Restangular.setDefaultHeaders({Authorization: "Bearer " + data.access_token});
When a user wants to access a route that has requiredAuth = true (set in the routeprovider as custom data like Access routeProvider's route properties) I check the user.current to see if its set.
a. If user.current is set, take them to the route.
b. If user.current is null or if the token would be expired (based on time) send them to /login
Problems/Concerns
If I Ctrl+R I lose my user info and the user has to log in again.
a. Should I be saving off the bearer token or credentials into a cookie or something and have a user service try to grab that in the event that user.current == null?
Am I even approaching this right? Seems like something that literally 100% of people using AngularJS would want to do, yet, I can't find an example that aligns with my situation. Seems like Angular would have mechanisms built in to handle some of this auth routing business...
When do I need to be getting a new token/verifying the current one? Do I just let anyone with devtools set something like isAuthorized = true so they can get to /admin/importantThings but then let the calls to /api/important things fail because they don't have a valid bearer token or should I be verifying that they have a valid token before I even let them get to that route?
You could put it in localStorage (always kept) or sessionStorage (cleared when browser is closed). Cookies are technically also a possibility, but don't fit your use case that well (your back end checks a separate header and not a cookie)
I guess there are many ways to skin a cat.
Always depend on server-side checks. Client-side checks might offer some increased usability, but you can never depend on them. If you have a lot of buttons that result in going to a login screen, it will be faster if you keep the client-side check. If this is more the exception than the rule, you could instead redirect to the login page when you get a 401 Unauthorized when calling your back end.
Here is an example of how you can manage your token:
/* global angular */
'use strict';
(function() {
angular.module('app').factory('authToken', ['$window', function($window) {
var storage = $window.localStorage;
var cachedToken;
var userToken = 'userToken';
var authToken = {
setToken: function(token) {
cachedToken = token;
storage.setItem(userToken, token);
},
getToken: function() {
if (!cachedToken) {
cachedToken = storage.getItem(userToken);
}
return cachedToken;
},
isAuthenticated: function() {
return !!authToken.getToken();
},
removeToken: function() {
cachedToken = null;
storage.removeItem(userToken);
}
};
return authToken;
}]);
})();
As you can see I use "$window.localStorage" to store my token. Like "Peter Herroelen" said in hist post.

How to store user session in secha touch 2

Im using Sencha Touch 2 where i have a login form asking for username and password
now i want to store user details via Session/Cookie so the user can logout,
i browsed some links which i got
Sencha-touch : save login / password (save session, multi-tasks)
but im being an new to sench touch develpment
any help using code examples will be of very great input for me
Thanks in advance
You can use the HTML5 localStore object. For instance, when a user logs in and your server request is made, on the callback of a successful server request you can store any necessary data. Here is a snippet from one of my apps:
loginCallback: function(options, success, response) {
this.mainSplash.setMasked(false);
var responseOjbect = Ext.JSON.decode(response.responseText);
if (responseOjbect.success) {
this.clearLoginStorage(); //runs a function to clear some login storage values
if (rememberme) {
localStorage.setItem("rememberme", 1);
} else {
localStorage.setItem("rememberme", 0);
}
localStorage.setItem("userid", responseOjbect.userid);
localStorage.setItem("first_name", responseOjbect.first_name);
localStorage.setItem("last_name", responseOjbect.last_name);
localStorage.setItem("appsettingone", responseOjbect.appsettingone);
localStorage.setItem("appsettingtwo", responseOjbect.appsettingtwo);
localStorage.setItem("setdate", new Date());
if (!this.dashboard) {
Ext.create('myApp.view.Dashboard', {
//additional config
});
}
Ext.Viewport.setActiveItem(this.dashboard);
} else {
Ext.Msg.alert('Attention', responseOjbect.errorMessage, Ext.emptyFn);
}
}
Once you have set your localStorage items, they can be retrieved or removed like so:
localStorage.getItem("user_id"); //retrieve
localStorage.removeItem("userid"); //remove
So when you call your logout function, just don't remove any localStorage objects you want to keep. Then you can call localStorage.getItem("VALUE") to retrieve them upon next login
This is something which is managed by the server, not the client, so you want to look at , not at sencha itself.
On a guess that you are using php, for something really basic, take a look at:
http://www.html-form-guide.com/php-form/php-login-form.html

Resources