繁体   English   中英

使用UI路由器和令牌在AngularJS中重定向

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM