Lektion 21: Keine Zugangsdaten preisgeben beim Verbinden mit Diensten
Diese GraphQL-Query ruft Zugangsdaten aus einem Umgebungswert ab und verhindert, dass sie in der Antwort oder in den Logs ausgegeben werden, wodurch Sicherheitsrisiken vermieden werden:
query {
githubAccessToken: _env(name: "GITHUB_ACCESS_TOKEN")
@remove
_sendJSONObjectItemHTTPRequest(input:{
url: "https://api.github.com/repos/GatoGraphQL/GatoGraphQL",
method: PATCH,
options: {
auth: {
password: $__githubAccessToken
},
body: "{\"has_wiki\":false}"
}
})
}Im Folgenden wird erklärt, wie diese Query funktioniert.
Wie Zugangsdaten preisgegeben werden könnten
Beim Verbinden mit externen Diensten müssen wir häufig Zugangsdaten angeben. Zum Beispiel erfordert die REST API von GitHub ein Access-Token für Endpunkte, bei denen Daten privat sind oder verändert werden:
query {
_sendJSONObjectItemHTTPRequest(input:{
url: "https://api.github.com/repos/GatoGraphQL/GatoGraphQL",
method: PATCH,
options: {
auth: {
password: "{ GITHUB_ACCESS_TOKEN }"
},
body: "{\"has_wiki\":false}"
}
})
}Wir müssen sorgfältig vorgehen und vermeiden, unsere Zugangsdaten preiszugeben:
- In der GraphQL-Query: Zugangsdaten dürfen niemals in den Quellcode eingebettet werden, da sie dort im Klartext vorliegen und ein Sicherheitsrisiko darstellen
- In der GraphQL-Antwort: Wenn das Feld, das sich mit dem Dienst verbindet, einen Fehler erzeugt, wird in der GraphQL-Antwort unter dem Eintrag
errorseine Fehlermeldung hinzugefügt; diese Meldung könnte den Namen des fehlgeschlagenen Feldes zusammen mit seinen Argumenten ausgeben und so die Zugangsdaten preisgeben - In den Server-Logs: Wenn auf Zugangsdaten über eine Variable zugegriffen wird und diese Variable als URL-Parameter übergeben wird, könnte sie in den Logs des Webservers aufgezeichnet werden
GraphQL-Query, die keine Zugangsdaten preisgibt
Diese GraphQL-Query übermittelt die Zugangsdaten an die API von GitHub, ohne sie preiszugeben:
query {
githubAccessToken: _env(name: "GITHUB_ACCESS_TOKEN")
@remove
_sendJSONObjectItemHTTPRequest(input:{
url: "https://api.github.com/repos/GatoGraphQL/GatoGraphQL",
method: PATCH,
options: {
auth: {
password: $__githubAccessToken
},
body: "{\"has_wiki\":false}"
}
})
}Das liegt daran, dass:
- Die Zugangsdaten aus der Umgebungsvariable
GITHUB_ACCESS_TOKENabgerufen werden und daher nicht in den Quellcode eingebettet werden müssen - Das Feld
githubAccessTokenmit@removeentfernt wird und daher nicht in der Antwort ausgegeben wird - Der Input
_sendJSONObjectItemHTTPRequest(auth:)auf die dynamische Variable$__githubAccessTokenverweist, sodass bei einem Fehler des Feldes der Literalstring"$__githubAccessToken"in der Fehlermeldung ausgegeben wird (nicht sein Wert)
Um den letzten Punkt zu veranschaulichen: Wenn man der API von GitHub die URL eines nicht existierenden Repositorys "leoloso/NonExisting" übergibt, wird ein Fehler ausgelöst, und wir erhalten diese Antwort (beachte auth: {password: $__githubAccessToken} in der Fehlermeldung):
{
"errors": [
{
"message": "Client error: `PATCH https://api.github.com/repos/leoloso/NonExisting` resulted in a `404 Not Found` response:\n{\"message\":\"Not Found\",\"documentation_url\":\"https://docs.github.com/rest/repos/repos#update-a-repository\"}\n",
"locations": [
{
"line": 21,
"column": 3
}
],
"extensions": {
"path": [
"_sendJSONObjectItemHTTPRequest(input: {url: \"https://api.github.com/repos/leoloso/NonExisting\", method: PATCH, options: {auth: {password: $__githubAccessToken}, body: \"{\"has_wiki\":false}\"}})",
"query { ... }"
],
"type": "QueryRoot",
"field": "_sendJSONObjectItemHTTPRequest(input: {url: \"https://api.github.com/repos/leoloso/NonExisting\", method: PATCH, options: {auth: {password: $__githubAccessToken}, body: \"{\"has_wiki\":false}\"}})",
"id": "root",
"code": "PoP/ComponentModel@e1"
}
}
],
"data": {
"_sendJSONObjectItemHTTPRequest": null
}
}