【问题标题】:Why is Angular2 token localStorage not set when I set apiBase upon _tokenService.init()?当我在 _tokenService.init() 上设置 apiBase 时,为什么没有设置 Angular2 令牌 localStorage?
【发布时间】:2019-04-25 17:09:06
【问题描述】:

我在 localhost:3000 上有一个 Rails BE 应用程序,在 localhost:4200 上有一个 FE。我试图让令牌验证自动完成,我知道这是通过在 _tokenService.validateToken() 方法期间设置和检索 localStorage 发生的。

问题似乎是,一旦我(成功)登录,我在浏览器中查看了我的 localStorage,发现没有任何保存。因此,当我刷新页面时,没有 localStorage 作为我的 validateToken() 方法的一部分进行验证,因此会话不会在浏览器上维护。

我在这里缺少什么?我初始化此命令的方式有错误吗?每次都需要手动设置localStorage吗?如果是这样,怎么做?

app.component.ts

import { Component, ViewEncapsulation, OnInit } from '@angular/core';
import { Angular2TokenService } from 'angular2-token';
@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss'],
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    constructor(private _tokenService: Angular2TokenService) {
         this._tokenService.init({apiBase:'http://localhost:3000'});
    }
}

登录.component.ts

import { Component, OnInit } from '@angular/core';
import { Angular2TokenService, SignInData } from 'angular2-token';

@Component({
    selector: 'sign-in',
    templateUrl: 'sign-in.component.html'
})
export class SignInComponent {

    private _signInData: SignInData = <SignInData>{};
    private _output: any;

    constructor(private _tokenService: Angular2TokenService) { }

    // Submit Data to Backend
    onSubmit() {

        this._output = null;

        this._tokenService.signIn(this._signInData).subscribe(
            res => {
                this._signInData    = <SignInData>{};
                this._output        = res;
            }, error => {
                this._signInData    = <SignInData>{};
                this._output        = error;
            }
        );
    }
}

【问题讨论】:

    标签: angular devise local-storage


    【解决方案1】:

    我知道它是旧的,但是对于仍在寻找它的任何 Rails 用户,您需要告诉您的 Rails 应用程序公开必要的标头。否则您的客户端应用程序将无法读取它们,如果无法读取,则无法将其写入您的 localStorage。

    为此,请转到位于 /config/application.rb 的应用程序模块

    您应该在此处定义 CORS 政策。 (如果您没有设置,则应先设置,请参阅:https://github.com/cyu/rack-cors)。

    Rack::Cors 模块的ressource 方法允许您传递一个“公开”参数,以明确告诉您的Rails 应用程序向客户端公开特定标头。这里我们需要其中的几个:

    • 访问令牌
    • 客户
    • 到期
    • 令牌类型
    • uid

    我不会在这里详细说明它们,但你需要所有这些。 一旦这些标头被公开,您的客户端应用程序将能够读取它们,并且 angular2-token 库将能够在您的 localStorage 中设置它们。

    /config/application.rb 的代码示例

    module MyAwesomeRailsApp
      class Application < Rails::Application
        # possibly some code and comments and then:
        config.middleware.insert_before 0, Rack::Cors do
          allow do
            origins '*'
            resource '*', headers: :any, methods: [:get, :post, :options],
                     expose: ['access-token', 'client', 'expiry','token-type', 'uid'] 
          end
        end
      end
    end
    

    当然,您可能希望将策略限制在一个或几个域,而不是整个世界。您可能还希望/需要向methodsarray 添加更多动词(如:delete、:putetc...),但这是另一个主题。

    由于库已更改,您可能很难弄清楚这一点,但您实际上可以在 github 存储库的问题中找到此信息(似乎与此确切帖子相对应):https://github.com/neroniaky/angular-token/issues/198#issuecomment-349914649

    顺便说一句,新版 gem 的文档在这一点上仍然有效:https://devise-token-auth.gitbook.io/devise-token-auth/config/cors

    希望对您有所帮助。

    【讨论】:

      【解决方案2】:

      经过大量搜索和反复试验,解决方案是为特定路由设置代理。这可以通过在 Angular 应用程序的根目录中添加以下文件来完成

      proxy.config.json

      {
        "/auth": {
          "target": "http://localhost:3000",
          "secure": false
        }
      }
      

      也包括在你的

      package.json

      {
      ..
      ..
        "scripts": {
        ...
        ...
        "start": "ng serve  --proxy-config proxy.conf.json",
        ...
        ...
        }
      ..
      ..
      }
      

      这个问题基本上是发送的响应标头没有通过以下命令分配给我的浏览器 localStorage

      this._tokenService.init({apiBase:'http://localhost:3000'});
      

      把它改回

      this._tokenService.init(); 
      

      而是通过 angular2-token 中设置的 /auth 默认路由通过代理请求将所有请求路由到相应的 rails 路由。

      【讨论】:

        猜你喜欢
        • 2021-05-23
        • 2019-09-10
        • 1970-01-01
        • 2011-02-14
        • 2011-10-21
        • 1970-01-01
        相关资源
        最近更新 更多