Login-Skript in PHP, um OAuth2 für die Netatmo-API zu nutzen und Wetterdaten abzurufen.

Die API-Dokumentation dazu ist unter https://dev.netatmo.com/apidocumentation/oauth zu finden.

Voraussetzungen

  1. Netatmo-API-Client-ID und Client-Secret: Registriere eine Anwendung in der Netatmo-Developer-Konsole
  2. PHP mit cURL-Erweiterung: Stelle sicher, dass cURL in deiner PHP-Installation aktiviert ist.
				
					<?php
session_start();

// Konfiguration
define('CLIENT_ID', 'DEINE_CLIENT_ID'); // Netatmo Client-ID
define('CLIENT_SECRET', 'DEIN_CLIENT_SECRET'); // Netatmo Client-Secret
define('REDIRECT_URI', 'https://deine-domain.de/callback.php'); // Dein Redirect URI
define('AUTH_URL', 'https://api.netatmo.com/oauth2/authorize');
define('TOKEN_URL', 'https://api.netatmo.com/oauth2/token');

// Schritt 1: Weiterleitung zur Netatmo-Login-Seite
if (!isset($_GET['code'])) {
    $authUrl = AUTH_URL . '?' . http_build_query([
        'client_id' => CLIENT_ID,
        'redirect_uri' => REDIRECT_URI,
        'scope' => 'read_station', // Passe die benötigten Berechtigungen an
        'state' => bin2hex(random_bytes(16)) // Optional: Schutz vor CSRF-Angriffen
    ]);
    $_SESSION['oauth_state'] = $authUrl['state']; // State speichern
    header("Location: $authUrl");
    exit;
}

// Schritt 2: Authorization Code empfangen und Access Token abrufen
if (isset($_GET['code']) && isset($_GET['state'])) {
    // State validieren
    if ($_GET['state'] !== $_SESSION['oauth_state']) {
        die('Ungültiger State!');
    }
    
    // Authorization Code gegen Access Token tauschen
    $postFields = [
        'grant_type' => 'authorization_code',
        'client_id' => CLIENT_ID,
        'client_secret' => CLIENT_SECRET,
        'redirect_uri' => REDIRECT_URI,
        'code' => $_GET['code']
    ];
    
    $ch = curl_init(TOKEN_URL);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
    $response = curl_exec($ch);
    curl_close($ch);

    $data = json_decode($response, true);
    
    if (isset($data['access_token'])) {
        // Access Token erfolgreich erhalten
        $_SESSION['access_token'] = $data['access_token'];
        $_SESSION['refresh_token'] = $data['refresh_token'];
        $_SESSION['expires_in'] = time() + $data['expires_in'];

        echo "Login erfolgreich!";
        echo "<pre>";
        print_r($data); // Token-Daten anzeigen
        echo "</pre>";
    } else {
        die('Fehler beim Abrufen des Access Tokens: ' . $response);
    }
} else {
    die('Keine Authorization Code erhalten!');
}

				
			

Erklärung

  1. Schritt 1: Weiterleitung
    Der Benutzer wird zur Netatmo-Login-Seite weitergeleitet. Dort autorisiert er die Anwendung.

  2. Schritt 2: Token abrufen
    Nach der Autorisierung erhält deine Anwendung einen Authorization Code, der gegen ein Access Token eingetauscht wird.

  3. Access Token speichern
    Das Access Token wird in der Session gespeichert und kann für API-Aufrufe genutzt werden.

 

API-Aufruf mit Access Token

Nach dem Login kannst du die API mit dem Access Token aufrufen:

				
					<?php
require 'vendor/autoload.php'; // Autoloader von Composer

use League\OAuth2\Client\Provider\GenericProvider;

// Konfiguration
define('CLIENT_ID', 'DEINE_CLIENT_ID');         // Netatmo Client-ID
define('CLIENT_SECRET', 'DEIN_CLIENT_SECRET'); // Netatmo Client-Secret
define('REDIRECT_URI', 'https://deine-domain.de/callback.php'); // Dein Redirect URI

// Netatmo API URLs
define('AUTH_URL', 'https://api.netatmo.com/oauth2/authorize');
define('TOKEN_URL', 'https://api.netatmo.com/oauth2/token');
define('API_BASE_URL', 'https://api.netatmo.com/api/');

// OAuth2-Provider einrichten
$provider = new GenericProvider([
    'clientId'                => CLIENT_ID,
    'clientSecret'            => CLIENT_SECRET,
    'redirectUri'             => REDIRECT_URI,
    'urlAuthorize'            => AUTH_URL,
    'urlAccessToken'          => TOKEN_URL,
    'urlResourceOwnerDetails' => ''
]);

session_start();

// Schritt 3: Wetterdaten mit getstationsdata abrufen
$weatherData = getWeatherData($accessToken->getToken());

echo "<h1>Wetterdaten:</h1>";
echo "<pre>" . json_encode($weatherData, JSON_PRETTY_PRINT) . "</pre>";


// Funktion: Wetterdaten mit Access Token abrufen
function getWeatherData($_SESSION['access_token']) {
    $url = API_BASE_URL . 'getstationsdata';

    // API-Aufruf mit cURL
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        "Authorization: Bearer $accessToken"
    ]);
    $response = curl_exec($ch);
    curl_close($ch);

    return json_decode($response, true);
}


				
			

Es wird noch ein Mechanismus zum Erneuern des Access Tokens benötigt. Mit dem Refresh Token kann der abgelaufene Access Token erneuert werden.

Voraussetzungen

  1. Access Token und Refresh Token: Diese werden nach dem ersten Login-Prozess gespeichert.
  2. Netatmo-Client-ID und Client-Secret: Wie bereits erwähnt.
				
					<?php
session_start();

// Konfiguration
define('CLIENT_ID', 'DEINE_CLIENT_ID'); // Netatmo Client-ID
define('CLIENT_SECRET', 'DEIN_CLIENT_SECRET'); // Netatmo Client-Secret
define('TOKEN_URL', 'https://api.netatmo.com/oauth2/token');

// Funktion: Access Token mit Refresh Token erneuern
function refreshAccessToken($refreshToken) {
    $postFields = [
        'grant_type' => 'refresh_token',
        'client_id' => CLIENT_ID,
        'client_secret' => CLIENT_SECRET,
        'refresh_token' => $refreshToken,
    ];
    
    // cURL-Anfrage
    $ch = curl_init(TOKEN_URL);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
    $response = curl_exec($ch);
    curl_close($ch);

    $data = json_decode($response, true);

    if (isset($data['access_token'])) {
        // Erfolgreich neues Access Token erhalten
        $_SESSION['access_token'] = $data['access_token'];
        $_SESSION['refresh_token'] = $data['refresh_token'] ?? $refreshToken; // Eventuell neuer Refresh Token
        $_SESSION['expires_in'] = time() + $data['expires_in'];

        echo "Access Token erfolgreich erneuert!<br>";
        return $data;
    } else {
        // Fehlerbehandlung
        echo "Fehler beim Erneuern des Access Tokens: " . $response . "<br>";
        return false;
    }
}

// Überprüfung, ob ein Refresh Token verfügbar ist
if (isset($_SESSION['refresh_token'])) {
    $result = refreshAccessToken($_SESSION['refresh_token']);
    if ($result) {
        echo "Neues Access Token: " . $_SESSION['access_token'] . "<br>";
    }
} else {
    echo "Kein Refresh Token verfügbar. Bitte erneut einloggen.";
}

				
			

Ablauf

  1. Prüfen, ob ein Refresh Token vorhanden ist
    Das Skript überprüft, ob ein gültiges Refresh Token in der Session gespeichert ist. Andernfalls wird der Benutzer gebeten, sich erneut anzumelden.

  2. Neues Access Token abrufen
    Mit dem gespeicherten Refresh Token wird ein neues Access Token abgerufen und in der Session gespeichert.

  3. Daten aktualisieren
    Falls Netatmo einen neuen Refresh Token zurückgibt, wird auch dieser aktualisiert.

Copyright by Jörg Vathauer 2024