【问题标题】:Angular 2/.NET core - authorized content prerenderingAngular 2/.NET core - 授权内容预渲染
【发布时间】:2017-04-12 15:05:24
【问题描述】:

我正在尝试在 Angular 2 和 .net 核心上实现身份验证/授权(由此开始:https://github.com/aspnet/JavaScriptServices

我的身份验证令牌 (jwt) 的存储选项是什么 - 以便可以访问它?:

  • 来自客户端:在登录时写入,在需要更新令牌时,在发出 get/post 请求时读取
  • 从服务器:在节点预呈现应用程序时读取(相同的请求,但来自节点上下文)

我知道预呈现受保护的内容没有多大意义 - 因为它无论如何都不会被索引 - 但这会带来闪烁问题。由于节点无法访问此令牌(在我的场景中) - 服务器返回无内容的 html(以防内容需要授权)

目前我将令牌存储在浏览器的本地存储中:

localStorage.setItem('currentUser', JSON.stringify({ username: username, token: token }));

...显然node没有这个东西,无法访问...

简单的获取请求:

let headers = new Headers({ 'Authorization': 'Bearer ' + this.authenticationService.token });
let options = new RequestOptions({ headers: headers });
this.http.get(url, options).subscribe(response => callback(<any>response));

我真的很早就开始学习/采用这一点 - 我也会考虑任何其他身份验证方法,但它必须符合规则才能预呈现授权内容。

【问题讨论】:

    标签: node.js angular asp.net-core


    【解决方案1】:

    我能够通过使用 cookie 作为令牌存储,然后将令牌从 cookie 传递到 asp-prerender-module 来解决这个问题。

    客户端和服务器的存储服务:

    declare var tokenStorage: NodeTokenStorage;    
    
    @Injectable()
    export class TokenStorageService implements NodeTokenStorage {
    
        getItem(key: string): string {
            if (!isBrowser) {
                return tokenStorage.getItem(key);
            }
            else {
                return getCookie(key);
            }
        }
    
        setItem(key: string, value: string): void {
            if (!isBrowser) {
                tokenStorage.setItem(key, value);
            }
            else {
                setCookie(key, value, 1);
            }
        }
    
        removeItem(key: string): void {
            if (!isBrowser) {
                tokenStorage.removeItem(key);
            }
            else {
                removeCookie(key);
            }
        }
    }
    
    interface NodeTokenStorage {
        getItem(key: string): string;
        setItem(key: string, value: string): void;
        removeItem(key: string): void;
    }
    

    将 cookie 注入预渲染模块:

    <app
         asp-prerender-module="ClientApp/dist/main-server"
         asp-prerender-data='new { token = Context.Request.Cookies["token"] }'>
        Loading...
    </app>
    

    阅读方式如下(ClientApp/boot-server.ts):

    (global as any).tokenStorage = {
        getItem: function(key) {
            return this[key];
        },
        setItem: function (key, value) {
            this[key] = value;
        },
        removeItem: function(key) {
            this[key] = undefined;
        }
    }
    
    export default createServerRenderer(params => {
    
        (global as any).tokenStorage.setItem('token', params.data.token);
    
        return new Promise<RenderResult>((resolve, reject) => {
            const requestZone = Zone.current.fork({
                name: 'angular-universal request',
                properties: {
                    baseUrl: '/',
                    requestUrl: params.url,
                    originUrl: params.origin,
                    preboot: false,
                    document: '<app></app>'
                },
                onHandleError: (parentZone, currentZone, targetZone, error) => {
                    // If any error occurs while rendering the module, reject the whole operation
                    reject(error);
                    return true;
                }
            });
    
            return requestZone.run<Promise<string>>(() => platform.serializeModule(AppModule)).then(html => {
                resolve({ html: html });
            }, reject);
        });
    });
    

    然后 - 当应用程序启动时(在服务器端路由和 redux 存储设置之前):我会读取令牌以获取经过身份验证的用户所需的数据。这样,完整的 html 从服务器返回,包括所有的身份验证内容和用户特定的数据。

    参考: https://github.com/aspnet/JavaScriptServices/tree/dev/src/Microsoft.AspNetCore.SpaServices#server-side-prerendering

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-16
      • 2018-04-13
      • 1970-01-01
      • 2019-06-15
      • 1970-01-01
      • 1970-01-01
      • 2018-08-05
      • 1970-01-01
      相关资源
      最近更新 更多