Copy link to clipboard
Copied
I have an application implemented in Coldfusion and AngularJS.
I have an external authentication system used for the security of our applications. It's called in the file application.cfc of the application. When the user tries to access to the application, the authentication system is called and if the authentication is correct, the user can access to the application. I put in session some data about the users'roles.
This security system is defined with another url.
In views I have some forms with drop-down list populating thanks to *AJAX queries*.
As there is no refresh of the page (Single page application).
If the server session is out, the queries are not correctly executed: I obtain the server status 302, because the authentication tries to be launched and I can see in the colnsole:
Failed to load https://myAuthenticationSystem: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://myApplication' is therefore not allowed access.
I try to retrieve the status in my Angular JS script and I obtain the status 0 and data are null. Is it normal ??
I would like to fore the reload of the aaplication if the server session is out, for avoiding this kind of problem (ideally with a pop-up message in AngularJS "Session Expired. You are going redirected to the authentication..."). How can I do that?
Here my code:
application.cfc
<cfcomponent output="false" extends="RootApplication">
<cfset this.name = "myApp"/>
<cfset this.SessionManagement="yes"/>
<cfset this.clientStorage="registry"/>
<cfset this.clientManagement="yes"/>
<cfset this.SetDomainCookies = false/>
<cfset This.loginStorage="session">
<cfset This.sessionTimeout=CreateTimeSpan(0,1,0,0)>
<cfset This.applicationTimeout = CreateTimeSpan(0,0,2,0) >
<cffunction name="OnApplicationStart" access="public" returntype="boolean" output="false" hint="Fires when the application is first created.">
<cfreturn true />
</cffunction>
<cffunction name="onSessionStart">
// CALL THE AUTHENTICATION SYSTEM
..........................
</cffunction>
<cffunction name="onRequestStart">
// Check the user access
...........................
// PUT DATA IN SESSION
<cfset SESSION.userLogin = "#authenticationSystem.USERID#">
<cfset SESSION.tocken = "#authenticationSystem.tocken#" />
<cfset SESSION.userRoles = #userProfile.Roles#>
</cffunction>
</cfcomponent>
index.cfm
<cfheader name="Access-Control-Allow-Origin" value="*">
<!DOCTYPE html>
<html xmlns:ng="http://angularjs.org" ng-app="ContactsApp" class="ng-app:ContactsApp" id="ng-app">
<head>
............................
</head>
<body>
// TRANSFORM THE COLDFUSION VARIABLES IN JS VARIABLES FOR ANGULAR JS
<script type="text/javascript" language="JavaScript">
<cfoutput>
var #toScript(SESSION.userLogin, "userLogin")#;
var #toScript(SESSION.tocken, "tocken")#;
var #toScript(SESSION.userRoles, "userRoles")#;
</cfoutput>
</script>
<div>
<ng-view></ng-view>
</div>
............................
</body>
</html>
app.js
var app=angular.module('ContactsApp', ['ngRoute', 'ui.bootstrap', 'ngDialog', 'angular-popover']);
// register the interceptor as a service
app.factory('HttpInterceptor', ['$q', '$rootScope', function($q, $rootScope) {
return {
// On request success
request : function(config) {
// Return the config or wrap it in a promise if blank.
return config || $q.when(config);
},
// On request failure
requestError : function(rejection) {
//console.log(rejection); // Contains the data about the error on the request.
// Return the promise rejection.
return $q.reject(rejection);
},
// On response success
response : function(response) {
//console.log(response); // Contains the data from the response.
// Return the response or promise.
return response || $q.when(response);
},
// On response failure
responseError : function(rejection) {
//console.log(rejection); // Contains the data about the error.
//Check whether the intercept param is set in the config array.
//If the intercept param is missing or set to true, we display a modal containing the error
if (typeof rejection.config.intercept === 'undefined' || rejection.config.intercept)
{
//emitting an event to draw a modal using angular bootstrap
$rootScope.$emit('errorModal', rejection.data);
}
// Return the promise rejection.
return $q.reject(rejection);
}
};
}]);
app.config(function($routeProvider, $httpProvider, ngDialogProvider){
$httpProvider.defaults.cache = false;
if (!$httpProvider.defaults.headers.get) {
$httpProvider.defaults.headers.get = {};
}
// disable IE ajax request caching
$httpProvider.defaults.headers.get['If-Modified-Since'] = '0';
// Add the interceptor to the $httpProvider to intercept http calls
$httpProvider.interceptors.push('HttpInterceptor');
$routeProvider.when('/all-contacts',
{
templateUrl: 'template/allContacts.html',
controller: 'ctrlContacts',
})
.when('/view-contacts/:contactId',
{
templateUrl: 'template/viewContact.html',
controller: 'ctrlViewContacts'
})
.otherwise({redirectTo:'/all-contacts'});
});
)
app.controller('ctrlContacts', function ($scope, $timeout, MyTextSearch, ContactService){
// ACCESS TO THE JS VARIABLES
$scope.userRoles = userRoles;
$scope.userLogin = userLogin;
............
});
app.controller('ctrlViewContacts', function ($scope, $routeParams, MyTextSearch, ContactService, RequestService, ReportService){
// ACCESS TO THE JS VARIABLES
$scope.userRoles = userRoles;
$scope.userLogin = userLogin;
// EXECUTE AJAX QUERY
ContactService.loadCategory('undefined',0).success(function(categories, status, header, config){
$scope.categories = categories;
console.log("status:" + status);
})
.error(function (data, status, header, config) {
console.log("sessionExpired: " + sessionExpired);
console.log("ERROR ");
console.log("data: " + data);
console.log("status:" + status);
console.log("header: " + header);
console.log("config: " + config);
if (status==302) {
alert("Session expired - New Authentication requested");
window.location.replace(headers('http://intragate.test.ec.europa.eu/remed'));
}
if (status==0) {
alert("ERROR 0 - Session expired - New Authentication requested");
//$window.location.reload();
}
}).finally(function() {
console.log("finally finished repos");
});
});
.........................
Thanks in advance for your help.
Sebastien
Copy link to clipboard
Copied
If I may offer a suggestion. This probably isn't what you are looking for, but if I might suggest code that will keep the session alive, negating the need to re-authenticate.
I suggest creating a page (call it keepalive.cfm) that sets a session variable to equal a URL variable:
<cfif StructKeyExists(url,'ka')>
<cfset session.ka = url.ka />
</cfif>
In your main page, use AJaX to do a GET call to that keepalive.cfm page, and set it to run every five minutes:
function keepalive(){
$.get("keepalive.cfm?ka=yes"); //Assuming jQuery
}
setInterval("keepalive()",300000);
Just my two cents.
HTH,
^ _ ^
UPDATE: Now that I re-read that, you're probably NOT using jQuery. But if there is an Angular equivalent, or if you can build your own XHR, same principle applies.