首页 > 解决方案 > 如何在服务中包含私钥而不将其放在前端代码中?

问题描述

我正在尝试通过从服务器上的私有端点引入它来在服务中包含私有 API 密钥。我只是不确定如何将其放入所需的服务中。

老实说,我对如何做到这一点有点迷茫。这是我下面的服务。私有 API 密钥用于将移动通知推送到移动设备的 onesignal 帐户。

编辑问题:

我现在稍微修改了代码并使用了另一个名为 KeysService 的服务。然后这会创建允许我定义 this.authKey 值的响应 - 这是一个字符串,因为这是我需要的。

您会注意到,现在在构造函数中调用 getKey() 方法,并且 this.authKeys 的 console.log 正在打印我需要放置在其下方 sendNotification() 方法上的 Authorization Header 中的相关字符串。

import { Injectable } from '@angular/core';
import { OneSignal } from './onesignal';
import { environment } from '../environments/environments';
import { HttpClient, HttpHeaders, HttpBackend } from '@angular/common/http';

import { throwError } from 'rxjs';

import { KeysService } from './keys.service';

@Injectable({
  providedIn: 'root'
})
export class OnesignalService {

  authKey: string;

  api_url = environment.one_signal.api_url;

  private http: HttpClient;

  constructor(handler: HttpBackend, private keysService: KeysService) {
    this.http = new HttpClient(handler);
    this.getkey();
  }

  getkey() {
    this.keysService.getPrivateKeys()
      .subscribe(
        authKeys => {
          this.authKey = authKeys.data[0].key;
          console.log(this.authKey);
        }
      )
  }

  sendNotification(pushData: any) {
    const httpOptions = {
      headers: new HttpHeaders({
        "Content-Type": "application/json; charset=utf-8",
        "Authorization": "PRIVATE_API_KEY"
      })
    }
    return this.http.post<OneSignal>(this.api_url, pushData, httpOptions);
  }

  handleError(error) {
    let errorMessage = '';
    if (error.error) {
      errorMessage = error.error.message;
    } else {
      errorMessage = error;
    }
    return throwError(errorMessage);
  }
}

如何将 this.authKey 引入 sendNotification() 方法,例如(见下文):

sendNotification(pushData: any) {
    const httpOptions = {
      headers: new HttpHeaders({
        "Content-Type": "application/json; charset=utf-8",
        "Authorization": this.authKey
      })
    }
    return this.http.post<OneSignal>(this.api_url, pushData, httpOptions);
  }

我想我已经接近了,但我错过了一个让它设置的技巧。

标签: angularhttp-headersangular6

解决方案


您可以尝试以下方法。

  1. 当您从服务器接收私钥时(通常发生在用户登录后),将其存储在浏览器的本地存储中或作为cookie
  2. 在您的配置服务或类似服务中,有一个从本地存储或 cookie 读取此私钥的方法。
  3. 在需要的服务中注入配置服务以访问私钥。

此外,Authorization我建议不要为每个服务中的每个调用设置标头,而是使用HttpInterceptor为所有 http 请求设置此值。然后你只需要在那个拦截器中注入配置服务。

编辑:

将密钥存储在服务本身中:

根据您编辑的问题,您正在调用以获取构造函数本身中的私钥。您可以将密钥与服务中的任何其他变量一样存储。并在sendNotification()方法中使用它,就像您现在使用this.authKey. 你现在拥有的应该可以工作。

但是如果页面被重新加载,那么服务中的所有数据都会被清除。将再次调用服务构造函数,再次调用以获取私钥。

在页面重新加载时保持键:

如果您希望在页面重新加载时保留密钥,则可以将其存储在本地存储、会话存储或作为 cookie 中。

不在任何地方存储密钥:

如果您不想将密钥存储在任何地方,并且每次sendNotification()调用方法时都可以进行服务调用以获取私钥,那么您可以遵循以下方法。

您可以连续进行两次调用——第一次调用以获取私钥,然后使用从第一次调用收到的作为响应的私钥作为第二次调用中的 http 标头。

您可以使用 RxJS 中的 flatMap 来执行此操作。

sendNotification(pushData: any) {
   return this.keysService.getPrivateKeys()
      .flatMap(authKeys => {
         const httpOptions = {
           headers: new HttpHeaders({
             "Content-Type": "application/json; charset=utf-8",
             "Authorization": authKeys.data[0].key
          })
         };

         return this.http.post<OneSignal>(this.api_url, pushData, httpOptions);
    }
  }

推荐阅读