AngularJS没有拦截来自地址栏

时间:2015-06-22 19:30:43

标签: javascript angularjs node.js express

我正在创建一个使用JWT令牌进行身份验证的AngularJS应用程序。使用AngularJS拦截器传递令牌,如下所示。

'request': function(config)
        {
            if (store.get('jwt_token') != null)
            {
                config.headers['x-access-token'] = store.get('jwt_token');
            }
            else
            {
                config.headers['x-access-token'] = '';
            }

            return config;
        }

每当我访问任何 /restricted 页面时,一切正常。问题是,当我通过在地址栏中直接输入网址(或刷新页面)进入 /restricted 页面时,AngularJS会被规避,因此,拦截器不会拦截请求,并且不会传递令牌。

我已经搜索了一段时间,我找到了一些解决方案,例如用一段加载AngularJS的代码进行响应然后从那里进行重定向。但是,我正在寻找一种更简单/更简洁的方法,因为我可能会遗漏一些内容

我可以通过检查 x-access-token 来检测请求是否来自AngularJS,因为我总是传递它(如果用户未经过身份验证,则为空值)。< / p>

解决方案

亚历克斯的回答指出了确切的问题,谢谢Alex。

我昨天终于明白了。我使用的解决方案是确保所有请求都来自AngularJS,我有一个受限页面列表,如果有任何请求,我调用一个函数来验证和验证服务器端的JWT令牌如果它有效,请继续,否则,请转到登录页面。 关键是要确保所有请求都应该转到index.html以确保AngularJS正在处理路由。

这个链接帮助我解决了这个问题。

http://arthur.gonigberg.com/2013/06/29/angularjs-role-based-auth/

4 个答案:

答案 0 :(得分:2)

听起来好像Angular的路由器和服务器端点之间存在混淆。

您可能会在浏览应用程序时触发$ http配置,使用Angular路由器跟踪的URL(工作正常),而import android.content.Context; import android.content.res.Resources; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; public class HomePage extends Fragment { public HomePage(){} String[] listitems; int[] images = {R.drawable.cadburysilk,R.drawable.cadburys_dairymilk,R.drawable.perk, R.drawable.kitkat,R.drawable.nestlemunchchocolate,R.drawable.cadbury_bournville_bar, R.drawable.snickers}; ListView list; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreateView(inflater, container, savedInstanceState); View rootview = inflater.inflate(R.layout.activity_home_page, container, false); Resources res = getResources(); listitems=res.getStringArray(R.array.items); list = (ListView)rootview.findViewById(R.id.itemslist); AdapterClass adapterClass = new AdapterClass(HomePage.this.getActivity(), listitems, images); list.setAdapter(adapterClass); return rootview; } } class AdapterClass extends ArrayAdapter<String> { Context context; int[] images; String[] names; public AdapterClass(Context c, String[] items,int imgs[] ) { // TODO Auto-generated constructor stub super(c, R.layout.rowlayout, R.id.quantity, items ); this.context = c; this.images = imgs; this.names = items; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View row = inflater.inflate(R.layout.rowlayout, parent, false); ImageView imageView = (ImageView) row.findViewById(R.id.img); TextView textView = (TextView) row.findViewById(R.id.textView1); imageView.setImageResource(images[position]); textView.setText(names[position]); return row; } } URL是服务器 URL。

因此,当您在Angular应用程序之外(在浏览器中)请求任何/restricted时,它会将请求直接发送到服务器,而不是通过Angular路由器或应用程序。

基本上,您需要在Angular应用程序中创建/restricted上下文中的路由,在初始化时,运行$ http配置。您永远不应该直接在地址栏中调用服务器端点,restrictedindex.html)除外。

我建议使用名为/的Angular路由,以便当用户点击它时,它将始终使用您拥有的$ http方法,通过专用的Angular路由,调用服务器的{{1}内部端点,通过控制器。

答案 1 :(得分:2)

我在2个月前问了类似的问题。我所理解的是,通常在javascript前端框架之前,如何提供http请求:

  • 我们在地址栏中输入网址。
  • 浏览器发送请求。
  • 服务器获取请求。
  • 提供必要的html,js和css文件。
  • 浏览器呈现它。

但是随着最近向各种javascript前端框架的转变以及RESTful api.s的使用已经开始,请求需要具有授权标头。因此,在许多具有javascript框架的单页网页应用程序中,例如angularjs,

  • 对&#39; /&#39;的初始请求路由器已发送
  • 服务器将Web应用程序提供给您的浏览器
  • Web应用程序中的所有进一步路由都在您的前端应用程序中完成,因此&#34;#&#34;在你的网址之后。
  • 应用程序通过角度js从您的应用程序获取,更新,删除或发布请求。

所以当你从角度应用程序发出请求时。您的请求是从角度应用程序截取并被您的拦截器截获的。但是,当您从地址栏输入URL时,浏览器会直接向服务器发送请求,因为在请求的那一点,浏览器尚未加载您的角度Web应用程序。

我建议您将html5mode设置为false并在路线前放置#

localhost/#/restricted类似,并从路由提供商处进行路由。当您的路由前有#时,/的请求将转到服务器,您的应用程序将加载,并从您的应用程序中/restricted创建一个控制器,将http请求发送到所需的服务器端点。通过这种方式,请求将通过您的应用程序发送,并将被您的拦截器截获。刷新并直接在地址栏中输入地址也可以。

答案 2 :(得分:0)

我认为如果您访问 / restricted 页面,您的Angular应用程序将正常启动,这只是一个登录问题。

如果您没有令牌,则必须重定向到登录页面。您可以将登录显示为模态叠加,然后您无需切换页面。拦截器将监视状态401的响应结果。在这种情况下,拦截器将显示登录。成功登录后,拦截器将使用令牌执行原始请求。

您可以在angular app

中找到一个有效的例子

答案 3 :(得分:-2)

只需在Cookie中传递此令牌,而不是在标题中传递。