What I am looking to do I when a user comes to the index.html page I need the login module to do 2 things:
I need this to check if a user is authenticated ( which I think I already started with the "function authService" ) if the user has a valid token then change the ui-view to dashboard/dashboard.html and if the key is not valid or there is no key at all then load login/login.html into ui-view.
Once they have successfully logged in I want them to be routed to "dashboard/dashboard.html"
Here is my login script:
function authInterceptor(API) {
return {
request: function(config) {
if(config.url.indexOf(API) === 0) {
request.headers = request.headers || {};
request.headers['X-PCC-API-TOKEN'] = localStorage.getItem('token');
}
return config;
}
}
}
function authService(auth) {
var self = this;
self.isAuthed = function() {
localStorage.getItem('token');
}
}
function userService($http, API) {
$http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;';
$http.defaults.transformRequest = [function(data) {
return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
}];
var self = this;
self.login = function(username, pwd, ctrl) {
ctrl.requestdata = API + '/winauth' + '; with ' + username;
return $http.post(API + '/winauth', {
username: username,
pwd: pwd
})
};
var param = function(obj) {
var query = '', name, value, fullSubName, subName, subValue, innerObj, i;
for(name in obj) {
value = obj[name];
if(value instanceof Array) {
for(i=0; i<value.length; ++i) {
subValue = value[i];
fullSubName = name + '[' + i + ']';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + '&';
}
}
else if(value instanceof Object) {
for(subName in value) {
subValue = value[subName];
fullSubName = name + '[' + subName + ']';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + '&';
}
}
else if(value !== undefined && value !== null)
query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
}
return query.length ? query.substr(0, query.length - 1) : query;
};
}
function LoginCtrl(user) {
var self = this;
function handleRequest(res) {
self.responsedata = res;
self.message = res.data.message;
var authToken = res.data.auth_token;
localStorage.setItem('token', authToken);
}
self.login = function() {
this.requestdata = 'Starting request...';
user.login(self.username, self.pwd, self)
.then(handleRequest, handleRequest)
}
}
// Login Module
var login = angular.module('login', ["ui.router"])
login.factory('authInterceptor', authInterceptor)
login.service('user', userService)
login.service('auth', authService)
login.constant('API', 'http://myserver.com/api')
EDIT - I added this into my login controller to provide the login routes
login.config(function($httpProvider, $stateProvider, $urlRouterProvider) {
$httpProvider.interceptors.push('authInterceptor');
$urlRouterProvider.otherwise('/login');
$stateProvider
// HOME STATES AND NESTED VIEWS ========================================
.state('login', {
url: '/login',
templateUrl: 'login/login.html',
controller: "mainLogin",
controllerAs: "log"
})
// nested list with just some random string data
.state('dashboard', {
url: '/dashboard',
templateUrl: 'dashboard/dashboard.html',
})
})
login.controller('mainLogin', LoginCtrl)
Here is my index.html:
EDIT - I removed "ng-include" and added "ng-view" to control the routes.
<body ng-app="login" ng-controller="mainLogin as log" class="loginPage">
<div class="main" ui-view></div>
</body>
As you can see I have a function that is checking for the token in the users local storage:
function authService(auth) {
var self = this;
self.isAuthed = function() {
localStorage.getItem('token');
}
}
And I am loading it in the module as a service:
login.service('auth', authService)
This is where I am stuck. I don't know where to go from here. I don't even know if I am using my authService function properly. I am still learning a lot about AngularJS so its easy for me to get stuck. :)
Another thing you will notice is in my index.html file I am just loading the "login/login.html" partial as default. I need it to load either login.html or dashboard.html depending if they are logged in or not. And then also route them to dashboard.html once they have successfully logged in.
The script works great as far as hitting the auth API, authenticating the user and then storing a valid auth key on their local storage.
Anyone know how I can accomplish this?
There are two separate concerns that you are dealing with. The first, is to be able to determine if you are logged in. Assuming the user needs to be logged in for any state except the login state, you would implement it like so by listening for $stateChangeState events and verifying that the user is logged in:
login.run(function($state, authService) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
var authToken = authService.isAuthed();
if (!authToken && toState !== 'login') {
//not logged in, so redirect to the login view instead of the view
//the user was attempting to load
event.preventDefault();
$state.go('login');
}
})
});
This will put them on the login state if they haven't already logged in.
The second part is to redirect to the correct view after they login, which you would do in your login controller:
function LoginCtrl(user, $state) {
var self = this;
function handleRequest(res) {
self.responsedata = res;
self.message = res.data.message;
var authToken = res.data.auth_token;
localStorage.setItem('token', authToken);
//after successful login, redirect to dashboard
$state.go('dashboard');
}
self.login = function() {
this.requestdata = 'Starting request...';
user.login(self.username, self.pwd, self)
.then(handleRequest, handleRequest)
}
}