在开发的过程中,遇到身份验证的问题,如果在不登录的情况下直接访问项目的地址,怎么对用户的身份进行验证?常见的处理是:如果没有读取到用户的登录信息,则页面自动转向登录页面,那么作为开发人员,怎么实现此需
在开发的过程中,遇到身份验证的问题,如果在不登录的情况下直接访问项目的地址,怎么对用户的身份进行验证?常见的处理是:如果没有读取到用户的登录信息,则页面自动转向登录页面,那么作为开发人员,怎么实现此需求?目前据我所知的解决方案有两种。第一种是用ui-router提供的$stateChangeStart对于发生路由转换时进行判断,第二种则是用angular自带的拦截器进行处理。
先说第一种:$stateChangeStart
由于ui-router关心的是状态,所以我们可以在每次模板引擎被解析前触发此方法
// 路由改变时判断是否登录,未登录则跳转至登录页面$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) { // 这里用event.preventDefault()可以阻止模板解析 if (toState.name !== 'login' || fromState.name === 'login') { // 这里做身份验证的判断 // 如判断cookie,session等。 // 若判断不通过,则跳转至login页面 } });
其中toState和fromState参数是获取路由的前一个状态和下一个状态,当发生路由状态改变时,如果访问的不是登陆页面或者不是从登陆页面跳转时,执行身份判断。
但是这种方法是有缺陷的,1.用到了$rootScope. 2.基于ui-router.3.不稳定(项目中测试发现).由于问题的存在,所以可以采用第二种拦截器的方法解决这些问题。
拦截器 Angular Interceptor
在与后台交互的过程中,有时会希望俘获一些请求,在其发送到服务端之前进行操作,或者在服务器完成响应执行调用前处理,拦截器就是为此应运而生的一种方法。
$httpProvider 中有一个 interceptors 数组,而所谓拦截器只是一个简单的注册到了该数组中的常规服务工厂。拦截器提供了四个方法:request , requestError ,response 和responseError 来对请求和响应进行处理。具体介绍看这里:
要实现身份验证,可以在每次$http请求到后台之前进行验证
function requestInterceptor($cookies,) { var requestConfig = { request: function(config) { // 这里做身份验证的判断 // 如判断cookie,session等。 // 若判断不通过,则跳转至login页面 return config; } }; return requestConfig;}
该方法接收请求配置对象作为参数,然后必须返回配置对象或者 promise 。如果返回无效的配置对象或者 promise 则会被拒绝,导致 $http 调用失败。然后只需将创建的拦截器注册到$httpProvider的interceptors数组中即可。
module.config(['$httpProvider', function($httpProvider) { $httpProvider.interceptors.push('myInterceptor');}]);
在每次发送请求前,拦截器都会执行我们事先写好的判断代码,去做身份的验证。比stateChangeStart好的是,它在每次请求前都进行验证,而不只是对于路由切换时才验证。
拦截器可以做的事情还有很多,如请求恢复、loading等,搭配request , requestError ,response 和responseError实现即可,这里不做赘述。