[英]Redirecting in AngularJS using UI router and a token
我正在为Angular
SPA
(单页应用程序)编写代码。
在后端,它连接到用Java
编写的引擎,该引擎执行大多数处理(我不关心)。
我正在使用UI Router
进行路由。
问题
但是,有一个棘手的情况我无法完成。
登录时,我进行了API调用,该请求以JSON
格式返回响应。
如果我的呼叫成功(即登录凭据匹配),我将在返回的JSON
获得一个令牌,该令牌基本上只是一个由符号,字母和数字组成的字符串。
我将其保存在rootscope
,然后以$ rootScope.myToken的身份进行访问。
然后,我在后续的API调用中使用相同的令牌。
现在,我想在AngularJS
做的是将一个未登录的用户重定向到登录页面,并尝试通过在地址栏中输入URL直接访问某些URL。
我在这里找到了一个相当简单的方法: 如果未通过身份验证,则在所有路由上重定向以登录 。 但是,我无法使用令牌来实现。
题
我应该怎么做才能使令牌起作用? 除此答案外,任何其他建议也都欢迎。
PS:我在stackoverflow上尝试了多种方法,但发现它们在我的上下文中不起作用或过于复杂。
更新:我可以在代码中成功实现Simon H的答案。 但是,我面临的问题是,只有在我至少登录和退出了我的应用程序之后,这才可以重定向。 如果我尝试通过URL直接访问页面而不至少登录和注销一次,则此方法失败,并且我仍然可以访问页面。 有小费吗?
网上有很多关于angular和jwt的教程
我用那些来按照您的需要开发一些东西。 他们代码的关键部分在配置中
$httpProvider.interceptors.push(function($q, $location, $localStorage, $injector) {
return {
'request': function (config) {
config.headers = config.headers || {};
if ($localStorage.token) {
config.headers.Authorization = 'Bearer ' + $localStorage.token;
}
return config;
},
'responseError': function(response) {
/* 401, unauthorised:
- bad username / password
- token expired
403, forbidden - notAdmin
*/
// if(response.status === 401 || response.status === 403) {
if(response.status === 401) {
console.log("app.js: httpInterceptor caught 40x:", response);
$injector.get('$state').go('login');
}
// Replace reponse with rejected promise to prevent rest of execution
return $q.reject(response);
}
};
可能真的很晚(因为Angular2退出了,但是我仍然在回答是否有人仍在使用1.x),但是我一直在自己的时间上与Node发送JWT和Angular一起使用它,而我是通过UI路由器完成的。 Simon的解决方案将起作用,但是,我尽量不要触摸rootScope。
我实现了3种东西来使其正常工作。 授权服务,ngStorage模块和Ui路由器的状态的resolve属性。
ngStorage
这是一个公开$ localStorage和$ sessionStorage的模块。 您可以向其中添加任何对象,它将在浏览器中进行设置,直到您将其清除。
UI路由器状态的解析
1.x状态的官方文档resolve是一个映射到函数的属性,它将在状态初始化之前触发。 因此,在这里您可以进行状态依赖的微配置,并且也可以兑现承诺。
授权工厂
这是一家提供3服务的工厂。 登录,注销和isAuthenticated。 成功后,登录服务将在$ localStorage中设置令牌。 在依赖注入中,我将其与ngStorage的$ localStorage服务以及$ http和其他注入在一起。
现在,我解释我该如何做。
我总是将默认状态指向我的家庭状态,而不是登录状态。
我没有使用rootscope,而是将Authorization Factory的登录服务发布到服务器的登录端点(该端点将为我提供新的令牌)。 收到令牌后,将其设置为$ localStorage作为令牌。
然后,在解决我的家庭状态后,我调用了授权工厂的isAuthenticated服务,该服务仅检查$ localStorage中是否设置了令牌。 如果不是,则返回false。 如果返回false,则可以通过$ state.go('login');将原籍状态重定向转换为登录状态。
我得到的是,在每个$ http调用应用程序范围内,我都可以在控制器中注入Authorization的isAuthenticated服务,并使其检查令牌(哪个登录服务获得了哪个isAuthenticated也可以访问,因为它们位于同一位置厂)。 如果存在令牌,则提取该令牌并将其与我的数据一起发送到服务器。 然后,我的服务器可以执行其他令牌验证,例如检查其到期时间和填充物,并以401s或200s响应。
现在,这听起来很令人毛骨悚然,而且似乎不是DRY。 但是我想说的是,我在一个根父状态中执行所有这些操作,并将所有其他状态附加为子状态。 父级是抽象的,因此可以执行解析,因此无需初始化状态。 家庭可以是默认的非抽象状态。
我试图远离rootScopes和$ watches等东西,并且始终将它们作为最后的手段。 干杯!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.