Is it okay to implement a Service within the $stateProvider
for this purpose?
I have read various posts on stack overflow regarding routing, but most of them seem confusing, especially for beginners. Everyone seems to have a different approach, making it seem like rocket science. I want to develop good habits from the start and avoid bad ones...
Objective: run some functions before the application starts and, based on the output, route my end user accordingly.
What I have tried:
Implemented a Service >> AuthService
| Actions >> simple check for:
- Fetching JWT token from the client Side (SQLite DB) - Token contains basic details + API Key
- Sending it to the server for authentication
- Receiving a response (Boolean)
- If Authorized >> load Home View. Otherwise, redirect to register View.
- Server-side validation takes place before loading any view
Service Providers
myApp.factory('AuthService', function (Session) {
var authService = {};
authService.isAuthorized = function(){
return Session.authorized();
};
return authService;
});
myApp.service('Session', function ($resource, $q, $timeout, URL_Config) {
this.authorized = function () {
var deferred = $q.defer();
$timeout(function () {
var db = window.openDatabase("config.db", "1.0", "Config", 2 * 1024 * 1024);
db.transaction(function (tx) {
tx.executeSql("SELECT * FROM user_details", [], function (tx, data) {
var token = data.rows.item(0).token;
var request = $resource(URL_Config.BASE_URL + '/authCheck', {token: token },
{ query: {
isArray: false,
method: 'GET'
} });
request.query(function (res) {
if (res.error) {
deferred.resolve(false);
} else {
deferred.resolve(true);
}
});
}, function (e) {
deferred.resolve(false);
});
});
}, 500);
return deferred.promise;
};
return this;
});
Route Configuration
This is the part I am struggling with. Where and how should I inject this Service? I managed to get it working, but I'm unsure if this is the correct way to handle it.
- Should I call the Service within the Resolve Property of
$stateProvider
? - Based on the value of
AuthService
, should I redirect to a view? - Should this process happen before the application starts?
myApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'templates/home.html',
controller: 'MainController',
resolve: ['AuthService', function(AuthService, $location, $q){
var deferred = $q.defer();
var authChk = AuthService.isAuthorized();
authChk.then(function(data){
if(!data){
$location.path('/register');
deferred.resolve();
} else{
$location.path('/home');
deferred.resolve();
}
}, function(e){
$location.path('/register');
deferred.resolve();
});
return deferred.promise;
}]
})
.state('register', {
url: '/register',
templateUrl: 'templates/register.html',
controller : 'RegisterController',
resolve: ['AuthService', function(AuthService, $location, $q){
var deferred = $q.defer();
var authChk = AuthService.isAuthorized();
authChk.then(function(data){
if(!data){
$location.path('/register');
deferred.resolve();
} else{
$location.path('/home');
deferred.resolve();
}
}, function(e){
$location.path('/register');
deferred.resolve();
});
return deferred.promise;
}]
})
});
Is this the proper place to run such Authentication validation?
This is a simple Hello World demo to help me get started with Angular. I don't have navigation (multiple views), so the check should be straightforward.
I have seen many examples using locationChangeStart
to fire a service before a view is loaded. Then $scope.watch
and $broadcast
are used when handling sessions (which is not the case here), but might be useful for future use.
Thank you. Any advice on how and where to handle this scenario is welcomed.