我有一个拦截器,可以处理我控制器上的所有请求。我有一个实现刷新令牌的后端Web API,但当我尝试刷新令牌并继续发出请求时,我得到“对预检请求的响应未通过访问控制检查:否'访问控制 - 允许-Origin'标题出现在请求的资源上。因此,不允许原点'http://localhost'访问。响应的HTTP状态代码为400.“令牌请求给了我{“error”:“invalid_clientId”,“error_description”:“应该发送ClientId。”}
拦截器:
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 the config or wrap it in a promise if blank.
return config || $q.when(config);
},
requestError: function (rejection) {
debugger; //return debugger for more info
return rejection;
},
responseError: function (rejection) {
debugger;
if (rejection.status === 401) {
var refreshToken = window.localStorage.getItem("refreshToken"); //log the user in if there is an 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");
}]);
服务
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 the 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 the global values for user
$rootScope.globals.accessToken = data.access_token;
$rootScope.globals.refreshToken = data.refresh_token;
//hide the menu items for which the users does not have access rights
$rootScope.HideMenuItems();
//navigate to the page where the user originally wanted to go (returnLocation) or to the default page
var gotoLocation = $rootScope.globals.returnToLocation;
if (gotoLocation != "") {
$location.path(gotoLocation);
$rootScope.globals.returnToLocation = "";
} else {
//go to default page
$location.path("/home");
}
//set the logged in value only after the navigation has taken place as it is linked to the ng-show/hide of the toolbar and menu
$rootScope.globals.isLoggedIn = true;
}
};
}]);
登录:
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 the 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 a username and password!";
$scope.LoginButtonDisabled = false;
}
};
var accessToken = window.localStorage.getItem("accessToken"); //log the user in if there is an access token
var refreshToken = window.localStorage.getItem("refreshToken"); //log the user in if there is an 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 to be used to 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 this for the auth-interceptor to do its 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 a 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 this for the auth-interceptor to do its work
$rootScope.globals.refreshToken = data.refresh_token //Set the 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 the time logged in and the 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 the access token
tokenExpired = false //renew to 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;
});
}
}]);
非常感谢任何帮助。
答案 0 :(得分:1)
我已经设法解决了我自己的问题,在拦截器上我注入了authService函数并重置了localstorage访问,然后我添加了" ALLOW OPTION"要在我的网络API上解决选项请求:
<强>拦截强>
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 the config or wrap it in a promise if blank.
return config || $q.when(config);
},
requestError: function (rejection) {
debugger;
return rejection;
},
responseError: function (response) {
// error - was it 401 or something else?
if (response.status === 401) {
var deferred = $q.defer(); // defer until we can re-request a new token
var accessToken = window.localStorage.getItem("accessToken");
var refreshtoken = window.localStorage.getItem("refreshToken");
// Get a new token... (cannot inject $http directly as will cause a circular ref)
$injector.get("authenticationService").RefreshToken(refreshtoken).then(function (loginResponse) {
if (loginResponse) {
console.log(loginResponse);
$rootScope.globals.accessToken = loginResponse.data.access_token; // we have a new acces token - set at $rootScope
$rootScope.globals.refreshToken = loginResponse.data.refresh_token; // we have a new refresh token - set at $rootScope
//Update the 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());
// now let's retry the original request - transformRequest in .run() below will add the new OAuth token
$injector.get("authenticationService").ResolveDeferred(response.config).then(function (defResp) {
// we have a successful response - resolve it using deferred
deferred.resolve(defResp);
}, function (defResp) {
deferred.reject(); // something went wrong
});
} else {
deferred.reject(); // login.json didn't give us data
}
}, function (response) {
deferred.reject(); // token retry failed, redirect so user can login again
$location.path('/login');
return;
});
return deferred.promise; // return the deferred promise
}
return $q.reject(response); // not a 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);
}