遇到此问题的背景:项目须要实现单点登陆,在先后端分离的前提下,前台如何保存token值成为了一个问题。想到的解决方案是,将token值统一存到一个前端程序,其余的前端程序去这个前端程序去取token(其余更好的解决方案欢迎指导~~)。在项目用angular的状况下,选择了如下插件:angular-cross-storage,此插件能够实现跨域存取localStorage,操做很是简单,都有demo。前端
一般状况下,设置HTTP的authorization只需在congfig中进行以下配置:git
var app = angular.module("myApp",[]);
app.config(function($httpProvider) {
$httpProvider.defaults.headers.common["Authorization"] = 所需带的权限;
});
可是在此处,权限值是存在另外一个前端程序的token值,获取权限token值是异步请求,并不能肯定在什么时候能完成,说不定还没获得token值,页面已经发出了http请求,而这个没设置Authorization的请求,势必会返回401。github
So 先要设置一个拦截器,并在拦截器里设置请求头,代码以下:后端
var app = angular.module("myApp",[ 'angular-cross-storage' ]); // 拦截器服务 app.factory("HttpInterceptor", function ($q, tokenService) { var HttpInterceptor = { request: function(config){ var deferred = $q.defer(); tokenService.getTokenEvents().then(function(res) { // 从另外一个前端程序获取token config.headers["Authorization"] = "bearer " + res.value; // 设置Authorization deferred.resolve(config); }).catch(function (err) { // do something... deferred.resolve(config); }); return deferred.promise; }, requestError: function(err){ return $q.reject(err); }, response: function(res){ console.log(res); return res; }, responseError: function(err){ if(-1 === err.status) { console.log(-1); // 远程服务器无响应 } else if(500 === err.status) { // 处理各种自定义错误 } else if(401 === err.status) { } return $q.reject(err); } }; return HttpInterceptor; }
拦截器依赖一个对token操做的服务“tokenService", 代码以下:跨域
// token的存取及清除 app.factory("tokenService", function (CrossDomainStorage) { // CrossDomainStorage 是angular-cross-storage 的一个服务 var setToken = function (access_token) { return CrossDomainStorage.set("access_token",access_token) }; var setTokenType = function (token_type) { return CrossDomainStorage.set("token_type", token_type) }; var getToken = function () { return CrossDomainStorage.get('access_token') }; var clearToken = function () { return CrossDomainStorage.clear() }; return { setTokenEvents: function (access_token) { return setToken(access_token) }, setTokenTypeEvents: function (token_type) { return setTokenType(token_type) }, getTokenEvents: function () { return getToken(); }, clearTokenEvents: function () { return clearToken(); } } })
而后在config中配置拦截器, 代码以下:promise
app.config(function ($httpProvider,CrossDomainStorageProvider) { $httpProvider.interceptors.push('HttpInterceptor'); })
就大功告成了,页面发起的请求都会带上 从另外一前端程序取过来的 token值权限头。服务器