javascript - Angular, Response to Preflight Request -
i have interceptor handles requests on controllers. have back-end web api implements refresh token when try refresh token , continue request being made "response preflight request doesn't pass access control check: no 'access-control-allow-origin' header present on requested resource. origin 'http://localhost' therefore not allowed access. response had http status code 400." , token request gives me {"error":"invalid_clientid","error_description":"clientid should sent."}
interceptor:
var appinterceptors = angular.module("auth-interceptor", ["ngroute", "angular-loading-bar"]); /* ==== bearer token headers configuration ==== */ appinterceptors.factory("authentication-interceptor", ["$q", "$injector", "$rootscope", "$location", "cfploadingbar", function ($q, $injector, $rootscope, $location, cfploadingbar) { var inflightauthrequest = null; var deferred = $q.defer(); return { // on request success request: function (config) { config.headers = config.headers || {}; if ($rootscope.globals.accesstoken != null) { config.headers.authorization = 'bearer ' + $rootscope.globals.accesstoken; } // return config or wrap in promise if blank. return config || $q.when(config); }, requesterror: function (rejection) { debugger; //return debugger more info return rejection; }, responseerror: function (rejection) { debugger; if (rejection.status === 401) { var refreshtoken = window.localstorage.getitem("refreshtoken"); //log user in if there refresh token $injector.get("$http").post( $rootscope.globals.apipath + "/accesscontrol/token", { client_id: "id", grant_type: "refresh_token", refresh_token: refreshtoken }, { 'content-type': 'application/x-www-form-urlencoded' } ) .then(function (data) { inflightauthrequest = null; if (data.access_token != undefined && data.refresh_token != undefined) { window.localstorage.setitem("refreshtoken", data.refresh_token); window.localstorage.setitem("accesstoken", data.access_token); window.localstorage.setitem("rememberme", true); window.localstorage.setitem("time_expires_in", data.expires_in); $injector.get("$http")(rejection.config).then(function (resp) { deferred.resolve(resp); }, function (resp) { deferred.reject(); }); } else { deferred.reject(); } return $q.reject(rejection); }, function (response) { deferred.reject(); authservice.clear(); $injector.get("$state").go('/login'); return; }); return deferred.promise; } } }; }]); appinterceptors.config(["$httpprovider", function ($httpprovider) { $httpprovider.interceptors.push("authentication-interceptor"); }]);
service:
jobmanagerapp.factory("authenticationservice", ["$rootscope", "$http", "$location", function ($rootscope, $http, $location) { return { login: function (username, password) { return $http({ url: $rootscope.globals.apipath + "/accesscontrol/token", method: 'post', data: "username=" + encodeuricomponent(username) + "&password=" + encodeuricomponent(password) + "&scope=" + "website" + "&grant_type=password" + "&client_id=id", headers: { 'content-type': 'application/x-www-form-urlencoded' } }); }, refreshtoken: function (refreshtoken) { return $http({ url: $rootscope.globals.apipath + "/accesscontrol/token", method: 'post', data: "client_id=" + "&grant_type=refresh_token" + "&refresh_token=" + refreshtoken, headers: { 'content-type': 'application/x-www-form-urlencoded' } }); }, logout: function () { return $http({ url: $rootscope.globals.apipath + "/accesscontrol/logout", method: "post" }); }, dologin: function (data, rememberme) { //save tokens if (rememberme == true) { window.localstorage.setitem("refreshtoken", data.refresh_token); window.localstorage.setitem("accesstoken", data.access_token); window.localstorage.setitem("rememberme", true); } else { window.localstorage.removeitem("refreshtoken"); window.localstorage.removeitem("accesstoken"); } //set global values user $rootscope.globals.accesstoken = data.access_token; $rootscope.globals.refreshtoken = data.refresh_token; //hide menu items users not have access rights $rootscope.hidemenuitems(); //navigate page user wanted go (returnlocation) or default page var gotolocation = $rootscope.globals.returntolocation; if (gotolocation != "") { $location.path(gotolocation); $rootscope.globals.returntolocation = ""; } else { //go default page $location.path("/home"); } //set logged in value after navigation has taken place linked ng-show/hide of toolbar , menu $rootscope.globals.isloggedin = true; } }; }]);
login:
jobmanagerapp.controller("logincontroller", ["$scope", "$rootscope", "$location", "authenticationservice", function ($scope, $rootscope, $location, authenticationservice) { $scope.loginbuttondisabled = false; $scope.logonname = null; $scope.password = null; $scope.error = ""; $scope.version = ($rootscope.globals.version.indexof("-") == -1) ? $rootscope.globals.version : $rootscope.globals.version.substring(0, $rootscope.globals.version.indexof("-")); $scope.login = function () { $scope.loginbuttondisabled = true; if ($scope.logonname !== null && $scope.password !== null) { //attempt login authenticationservice.login($scope.logonname, $scope.password) .success(function (data) { $scope.loginbuttondisabled = false; if (data.access_token != undefined) { //time expires window.localstorage.setitem("time_expires_in", data.expires_in); //time user logged in window.localstorage.setitem("time_logged_in", new date().gettime()); //do actual login authenticationservice.dologin(data, $scope.rememberme); } else if (data.error_description != undefined) { $scope.error = data.error_description; } else { $scope.error = "unexpected error occurred!"; } }) .error(function (data, status, headers, config) { $rootscope.globals.accesstoken = null; window.localstorage.removeitem("accesstoken"); window.localstorage.removeitem("refreshtoken"); $scope.loginbuttondisabled = false; }); } else { $scope.error = "enter username , password!"; $scope.loginbuttondisabled = false; } }; var accesstoken = window.localstorage.getitem("accesstoken"); //log user in if there access token var refreshtoken = window.localstorage.getitem("refreshtoken"); //log user in if there refresh token var time_expires = window.localstorage.getitem("time_expires_in"); //time token expires var time_logged_in = window.localstorage.getitem("time_logged_in"); //time user logged in var time = new date().gettime(); //currenttime var tokenexpired; //variable used setexpired if (((time / 1000) - (time_logged_in / 1000)) >= time_expires) { tokenexpired = true; } else { tokenexpired = false; } //log test console.log("time left: " + (time_expires - ((time / 1000) - (time_logged_in / 1000)))); console.log(refreshtoken); //login if (accesstoken != null && tokenexpired == false && refreshtoken != null) { $rootscope.globals.accesstoken = accesstoken; //set auth-interceptor work $rootscope.globals.showloading = true; $rootscope.globals.showloading = false; var data = { access_token: accesstoken, expires_in: time_expires, refresh_token: refreshtoken }; authenticationservice.dologin(data, true); //authenticationservice.getauthenticationproperties().success(function (data) { // $rootscope.globals.showloading = false; // data.access_token = accesstoken; // authenticationservice.dologin(data, true); //}).error(function () { // $rootscope.globals.showloading = false; //}); } else if (refreshtoken != null) { //request new access token authenticationservice.refreshtoken(refreshtoken) .success(function (data) { if (data.access_token != undefined && data.refresh_token != undefined) { $rootscope.globals.accesstoken = data.access_token; //set auth-interceptor work $rootscope.globals.refreshtoken = data.refresh_token //set new refresh token $rootscope.globals.showloading = true; $rootscope.globals.showloading = false; var data = { access_token: data.access_token, refresh_token: data.refresh_token, expires_in: data.expires_in }; //renew time logged in , time time_expires //time expires window.localstorage.setitem("time_expires_in", data.expires_in); //time user logged in window.localstorage.setitem("time_logged_in", new date().gettime()); //set access token tokenexpired = false //renew false; authenticationservice.dologin(data, true); } }) .error(function (data, status, headers, config) { $rootscope.globals.accesstoken = null; window.localstorage.removeitem("accesstoken"); window.localstorage.removeitem("refreshtoken"); $scope.loginbuttondisabled = false; }); } }]);
any appreciated.
i have managed fix own problem, on interceptor injected authservice functions , reset localstorage access, added , "allow option" option requests resolved on web api:
interceptor
appinterceptors.factory("authentication-interceptor", ["$q", "$injector", "$rootscope", "$location", "cfploadingbar", function ($q, $injector, $rootscope, $location, cfploadingbar) { return { // on request success request: function (config) { config.headers = config.headers || {}; if ($rootscope.globals.accesstoken != null) { config.headers.authorization = 'bearer ' + $rootscope.globals.accesstoken; } // return config or wrap in promise if blank. return config || $q.when(config); }, requesterror: function (rejection) { debugger; return rejection; }, responseerror: function (response) { // error - 401 or else? if (response.status === 401) { var deferred = $q.defer(); // defer until can re-request new token var accesstoken = window.localstorage.getitem("accesstoken"); var refreshtoken = window.localstorage.getitem("refreshtoken"); // new token... (cannot inject $http directly cause circular ref) $injector.get("authenticationservice").refreshtoken(refreshtoken).then(function (loginresponse) { if (loginresponse) { console.log(loginresponse); $rootscope.globals.accesstoken = loginresponse.data.access_token; // have new acces token - set @ $rootscope $rootscope.globals.refreshtoken = loginresponse.data.refresh_token; // have new refresh token - set @ $rootscope //update headers window.localstorage.setitem("accesstoken", loginresponse.data.access_token); window.localstorage.setitem("refreshtoken", loginresponse.data.refresh_token); window.localstorage.setitem("rememberme", true); //time expires window.localstorage.setitem("time_expires_in", loginresponse.data.expires_in); //time user logged in window.localstorage.setitem("time_logged_in", new date().gettime()); // let's retry original request - transformrequest in .run() below add new oauth token $injector.get("authenticationservice").resolvedeferred(response.config).then(function (defresp) { // have successful response - resolve using deferred deferred.resolve(defresp); }, function (defresp) { deferred.reject(); // went wrong }); } else { deferred.reject(); // login.json didn't give data } }, function (response) { deferred.reject(); // token retry failed, redirect user can login again $location.path('/login'); return; }); return deferred.promise; // return deferred promise } return $q.reject(response); // not recoverable error } }; }]);
authenticationservice
refreshtoken: function (refreshtoken) { return $http({ url: $rootscope.globals.apipath + "/accesscontrol/token", method: 'post', datatype: 'jsonp', data: "client_id=id" + "&grant_type=refresh_token" + "&refresh_token=" + refreshtoken, headers: { 'content-type': 'application/x-www-form-urlencoded' } }); }, logout: function () { return $http({ url: $rootscope.apipath + "/acess/logout", method: "post" }); }, resolvedeferred: function (config) { return $http(config); },
api
public override task matchendpoint(oauthmatchendpointcontext context) { if (context.istokenendpoint && context.request.method == "options") { context.owincontext.response.headers.add("access-control-allow-origin", new[] { "*" }); context.owincontext.response.headers.add("access-control-allow-headers", new[] { "authorization" }); context.requestcompleted(); return task.fromresult(0); } return base.matchendpoint(context); }
Comments
Post a Comment