Authentifizierung
Bevor Ihre Anwendung eine Methode aufrufen darf, meldet sie sich beim Anmeldedienst (IdentityServer) von Netxp-Verein an und erhält dafür ein Access Token — einen zeitlich begrenzten Zugangsausweis. Dieses Token schickt sie bei jedem Aufruf im HTTP-Header mit:
Authorization: Bearer <access_token>
Die Adressen des Anmeldedienstes finden Sie in der Übersicht. Wie Sie den zugehörigen API-Client einrichten, beschreibt die Seite API-Clients.
Anmeldewege im Überblick
| Anmeldeweg | MO-API | VO-API | Verein-API | Wer meldet sich an? | Zugriffsart im API-Client |
|---|---|---|---|---|---|
| E-Mail-Adresse und Passwort | ✓ | – | – | Ein Mitglied | Password |
| VereinsID, Benutzername und Passwort | – | ✓ | ✓ | Ein Benutzer des Vereins | Password |
| API-Schlüssel | – | ✓ | ✓ | Der API-Benutzer des Clients | API Key |
| Client Credentials | – | – | ✓ | Die Anwendung selbst | Client Credentials |
| Login über Browser | ✓ | ✓ | ✓ | Eine Person im Browser | Login über Browser |
Wessen Rechte beim jeweiligen Anmeldeweg gelten, steht unter Wer meldet sich an?.
Token anfordern
Für alle Anmeldewege außer Login über Browser schickt Ihre Anwendung
eine POST-Anfrage an die Token URL
https://zugang.netxp-verein.de/connect/token. Die Angaben stehen als
Formular im Inhalt der Anfrage
(Content-Type: application/x-www-form-urlencoded):
| Feld | Inhalt |
|---|---|
grant_type | Der Anmeldeweg, z. B. password oder api_key |
client_id | Die Client-ID Ihres API-Clients |
client_secret | Das Secret Ihres API-Clients |
scope | Die gewünschten Scopes, durch Leerzeichen getrennt |
| … | Je nach Anmeldeweg weitere Felder (siehe unten) |
client_id und client_secret können Sie statt im Formular auch per
HTTP-Basic-Authentifizierung im Header Authorization übergeben.
Mit Benutzerdaten (Passwort)
Die Anwendung nimmt die Anmeldedaten einer Person entgegen und reicht sie an den Anmeldedienst weiter. Es gelten die Rechte dieser Person. Welche Daten erwartet werden, hängt von der Schnittstelle ab:
- Mitglied (MO-API)
- Vereinsbenutzer (VO-API, Verein-API)
Mitglieder melden sich immer mit E-Mail-Adresse und Passwort ihres MitgliederOnline-Zugangs an — ohne Benutzername und ohne VereinsID.
| Feld | Wert |
|---|---|
grant_type | password |
username | Die E-Mail-Adresse des Mitglieds |
password | Das Passwort des Mitglieds |
- CMD
- Bash
- C#
- TypeScript
- PHP
- Python
REM ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veroeffentlichen.
REM Tragen Sie hier Ihre Werte ein:
set "CLIENT_ID=1234_mein_client"
set "CLIENT_SECRET=mein_secret"
set "EMAIL=mitglied@example.de"
set "PASSWORD=mein_passwort"
REM Token mit E-Mail-Adresse und Passwort des Mitglieds anfordern und die Antwort ausgeben
powershell -NoProfile -Command "$body = @{grant_type='password'; client_id='%CLIENT_ID%'; client_secret='%CLIENT_SECRET%'; username='%EMAIL%'; password='%PASSWORD%'; scope='mo_member'}; Invoke-RestMethod -Uri 'https://zugang.netxp-verein.de/connect/token' -Method Post -Body $body | ConvertTo-Json"
echo.
pause
# ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
# Tragen Sie hier Ihre Werte ein:
CLIENT_ID="1234_mein_client"
CLIENT_SECRET="mein_secret"
EMAIL="mitglied@example.de"
PASSWORD="mein_passwort"
# Token mit E-Mail-Adresse und Passwort des Mitglieds anfordern und die Antwort ausgeben
curl -s -X POST "https://zugang.netxp-verein.de/connect/token" \
--data-urlencode "grant_type=password" \
--data-urlencode "client_id=$CLIENT_ID" \
--data-urlencode "client_secret=$CLIENT_SECRET" \
--data-urlencode "username=$EMAIL" \
--data-urlencode "password=$PASSWORD" \
--data-urlencode "scope=mo_member"
echo
read -r -p "Mit Enter beenden ..."
// ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
// Tragen Sie hier Ihre Werte ein:
var clientId = "1234_mein_client";
var clientSecret = "mein_secret";
var email = "mitglied@example.de";
var password = "mein_passwort";
try
{
using var http = new HttpClient();
// Token mit E-Mail-Adresse und Passwort des Mitglieds anfordern
using var tokenResponse = await http.PostAsync(
"https://zugang.netxp-verein.de/connect/token",
new FormUrlEncodedContent(new Dictionary<string, string>
{
["grant_type"] = "password",
["client_id"] = clientId,
["client_secret"] = clientSecret,
["username"] = email,
["password"] = password,
["scope"] = "mo_member",
}));
// Antwort mit access_token, token_type und expires_in ausgeben
Console.WriteLine($"{(int)tokenResponse.StatusCode}: {await tokenResponse.Content.ReadAsStringAsync()}");
}
catch (Exception ex)
{
Console.WriteLine($"Fehler: {ex.Message}");
}
Console.Write("\nMit Enter beenden ...");
Console.ReadLine();
import { createInterface } from 'node:readline/promises';
// ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
// Tragen Sie hier Ihre Werte ein:
const clientId = '1234_mein_client';
const clientSecret = 'mein_secret';
const email = 'mitglied@example.de';
const password = 'mein_passwort';
try {
// Token mit E-Mail-Adresse und Passwort des Mitglieds anfordern
const tokenResponse = await fetch('https://zugang.netxp-verein.de/connect/token', {
method: 'POST',
body: new URLSearchParams({
grant_type: 'password',
client_id: clientId,
client_secret: clientSecret,
username: email,
password: password,
scope: 'mo_member',
}),
});
// Antwort mit access_token, token_type und expires_in ausgeben
console.log(tokenResponse.status, await tokenResponse.text());
} catch (error) {
console.error('Fehler:', error instanceof Error ? error.message : error);
}
const rl = createInterface({ input: process.stdin, output: process.stdout });
await rl.question('\nMit Enter beenden ...');
rl.close();
<?php
// ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
// Tragen Sie hier Ihre Werte ein:
$clientId = '1234_mein_client';
$clientSecret = 'mein_secret';
$email = 'mitglied@example.de';
$password = 'mein_passwort';
// Token mit E-Mail-Adresse und Passwort des Mitglieds anfordern
$ch = curl_init('https://zugang.netxp-verein.de/connect/token');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => http_build_query([
'grant_type' => 'password',
'client_id' => $clientId,
'client_secret' => $clientSecret,
'username' => $email,
'password' => $password,
'scope' => 'mo_member',
]),
]);
$result = curl_exec($ch);
// Antwort mit access_token, token_type und expires_in ausgeben
echo $result === false ? 'Verbindungsfehler: ' . curl_error($ch) : $result, PHP_EOL;
echo PHP_EOL, 'Mit Enter beenden ...';
fgets(STDIN);
import requests
# ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
# Tragen Sie hier Ihre Werte ein:
CLIENT_ID = "1234_mein_client"
CLIENT_SECRET = "mein_secret"
EMAIL = "mitglied@example.de"
PASSWORD = "mein_passwort"
try:
# Token mit E-Mail-Adresse und Passwort des Mitglieds anfordern
token_response = requests.post(
"https://zugang.netxp-verein.de/connect/token",
data={
"grant_type": "password",
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
"username": EMAIL,
"password": PASSWORD,
"scope": "mo_member",
},
timeout=30,
)
# Antwort mit access_token, token_type und expires_in ausgeben
print(token_response.status_code, token_response.text)
except requests.RequestException as error:
print(f"Verbindungsfehler: {error}")
input("\nMit Enter beenden ...")
Vereinsbenutzer melden sich wie im Netxp-Verein-Programm mit
VereinsID, Benutzername und Passwort an. Die VereinsID steht
dabei im Feld username, durch # vom Benutzernamen getrennt.
| Feld | Wert |
|---|---|
grant_type | password |
username | <VereinsID>#<Benutzername>, z. B. 1234#Admin |
password | Das Passwort des Benutzers |
- CMD
- Bash
- C#
- TypeScript
- PHP
- Python
REM ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veroeffentlichen.
REM Tragen Sie hier Ihre Werte ein:
set "CLIENT_ID=1234_mein_client"
set "CLIENT_SECRET=mein_secret"
set "CLUB_ID=1234"
set "USER_NAME=mein_benutzername"
set "PASSWORD=mein_passwort"
REM Token mit VereinsID, Benutzername und Passwort anfordern und die Antwort ausgeben
powershell -NoProfile -Command "$body = @{grant_type='password'; client_id='%CLIENT_ID%'; client_secret='%CLIENT_SECRET%'; username='%CLUB_ID%#%USER_NAME%'; password='%PASSWORD%'; scope='vo_member'}; Invoke-RestMethod -Uri 'https://zugang.netxp-verein.de/connect/token' -Method Post -Body $body | ConvertTo-Json"
echo.
pause
# ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
# Tragen Sie hier Ihre Werte ein:
CLIENT_ID="1234_mein_client"
CLIENT_SECRET="mein_secret"
CLUB_ID="1234"
USER_NAME="mein_benutzername"
PASSWORD="mein_passwort"
# Token mit VereinsID, Benutzername und Passwort anfordern und die Antwort ausgeben
curl -s -X POST "https://zugang.netxp-verein.de/connect/token" \
--data-urlencode "grant_type=password" \
--data-urlencode "client_id=$CLIENT_ID" \
--data-urlencode "client_secret=$CLIENT_SECRET" \
--data-urlencode "username=$CLUB_ID#$USER_NAME" \
--data-urlencode "password=$PASSWORD" \
--data-urlencode "scope=vo_member"
echo
read -r -p "Mit Enter beenden ..."
// ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
// Tragen Sie hier Ihre Werte ein:
var clientId = "1234_mein_client";
var clientSecret = "mein_secret";
var clubId = "1234";
var userName = "mein_benutzername";
var password = "mein_passwort";
try
{
using var http = new HttpClient();
// Token mit VereinsID, Benutzername und Passwort anfordern
using var tokenResponse = await http.PostAsync(
"https://zugang.netxp-verein.de/connect/token",
new FormUrlEncodedContent(new Dictionary<string, string>
{
["grant_type"] = "password",
["client_id"] = clientId,
["client_secret"] = clientSecret,
["username"] = $"{clubId}#{userName}",
["password"] = password,
["scope"] = "vo_member",
}));
// Antwort mit access_token, token_type und expires_in ausgeben
Console.WriteLine($"{(int)tokenResponse.StatusCode}: {await tokenResponse.Content.ReadAsStringAsync()}");
}
catch (Exception ex)
{
Console.WriteLine($"Fehler: {ex.Message}");
}
Console.Write("\nMit Enter beenden ...");
Console.ReadLine();
import { createInterface } from 'node:readline/promises';
// ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
// Tragen Sie hier Ihre Werte ein:
const clientId = '1234_mein_client';
const clientSecret = 'mein_secret';
const clubId = '1234';
const userName = 'mein_benutzername';
const password = 'mein_passwort';
try {
// Token mit VereinsID, Benutzername und Passwort anfordern
const tokenResponse = await fetch('https://zugang.netxp-verein.de/connect/token', {
method: 'POST',
body: new URLSearchParams({
grant_type: 'password',
client_id: clientId,
client_secret: clientSecret,
username: `${clubId}#${userName}`,
password: password,
scope: 'vo_member',
}),
});
// Antwort mit access_token, token_type und expires_in ausgeben
console.log(tokenResponse.status, await tokenResponse.text());
} catch (error) {
console.error('Fehler:', error instanceof Error ? error.message : error);
}
const rl = createInterface({ input: process.stdin, output: process.stdout });
await rl.question('\nMit Enter beenden ...');
rl.close();
<?php
// ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
// Tragen Sie hier Ihre Werte ein:
$clientId = '1234_mein_client';
$clientSecret = 'mein_secret';
$clubId = '1234';
$userName = 'mein_benutzername';
$password = 'mein_passwort';
// Token mit VereinsID, Benutzername und Passwort anfordern
$ch = curl_init('https://zugang.netxp-verein.de/connect/token');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => http_build_query([
'grant_type' => 'password',
'client_id' => $clientId,
'client_secret' => $clientSecret,
'username' => $clubId . '#' . $userName,
'password' => $password,
'scope' => 'vo_member',
]),
]);
$result = curl_exec($ch);
// Antwort mit access_token, token_type und expires_in ausgeben
echo $result === false ? 'Verbindungsfehler: ' . curl_error($ch) : $result, PHP_EOL;
echo PHP_EOL, 'Mit Enter beenden ...';
fgets(STDIN);
import requests
# ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
# Tragen Sie hier Ihre Werte ein:
CLIENT_ID = "1234_mein_client"
CLIENT_SECRET = "mein_secret"
CLUB_ID = "1234"
USER_NAME = "mein_benutzername"
PASSWORD = "mein_passwort"
try:
# Token mit VereinsID, Benutzername und Passwort anfordern
token_response = requests.post(
"https://zugang.netxp-verein.de/connect/token",
data={
"grant_type": "password",
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
"username": f"{CLUB_ID}#{USER_NAME}",
"password": PASSWORD,
"scope": "vo_member",
},
timeout=30,
)
# Antwort mit access_token, token_type und expires_in ausgeben
print(token_response.status_code, token_response.text)
except requests.RequestException as error:
print(f"Verbindungsfehler: {error}")
input("\nMit Enter beenden ...")
Mit einem API-Schlüssel melden sich nur API-Benutzer von Clients für die VO-API oder die Verein-API an. Für die MO-API gibt es keinen API-Schlüssel — dort meldet sich immer ein Mitglied an.
Mit API-Schlüssel
Die Anwendung meldet sich mit dem API-Schlüssel des API-Benutzers an. Es gelten die Benutzerrollen dieses API-Benutzers. Möglich bei VO-API und Verein-API.
| Feld | Wert |
|---|---|
grant_type | api_key |
apikey | Der API-Schlüssel aus dem Reiter API-Benutzer |
Beispiel für die Verein-API (Scope va_mitglied) — für die VO-API
tauschen Sie nur den Scope, z. B. gegen vo_member.
- CMD
- Bash
- C#
- TypeScript
- PHP
- Python
REM ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veroeffentlichen.
REM Tragen Sie hier Ihre Werte ein:
set "CLIENT_ID=1234_mein_client"
set "CLIENT_SECRET=mein_secret"
set "API_KEY=mein_api_schluessel"
REM Token mit dem API-Schluessel anfordern und die Antwort ausgeben
powershell -NoProfile -Command "$body = @{grant_type='api_key'; client_id='%CLIENT_ID%'; client_secret='%CLIENT_SECRET%'; apikey='%API_KEY%'; scope='va_mitglied'}; Invoke-RestMethod -Uri 'https://zugang.netxp-verein.de/connect/token' -Method Post -Body $body | ConvertTo-Json"
echo.
pause
# ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
# Tragen Sie hier Ihre Werte ein:
CLIENT_ID="1234_mein_client"
CLIENT_SECRET="mein_secret"
API_KEY="mein_api_schluessel"
# Token mit dem API-Schlüssel anfordern und die Antwort ausgeben
curl -s -X POST "https://zugang.netxp-verein.de/connect/token" \
--data-urlencode "grant_type=api_key" \
--data-urlencode "client_id=$CLIENT_ID" \
--data-urlencode "client_secret=$CLIENT_SECRET" \
--data-urlencode "apikey=$API_KEY" \
--data-urlencode "scope=va_mitglied"
echo
read -r -p "Mit Enter beenden ..."
// ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
// Tragen Sie hier Ihre Werte ein:
var clientId = "1234_mein_client";
var clientSecret = "mein_secret";
var apiKey = "mein_api_schluessel";
try
{
using var http = new HttpClient();
// Token mit dem API-Schlüssel anfordern
using var tokenResponse = await http.PostAsync(
"https://zugang.netxp-verein.de/connect/token",
new FormUrlEncodedContent(new Dictionary<string, string>
{
["grant_type"] = "api_key",
["client_id"] = clientId,
["client_secret"] = clientSecret,
["apikey"] = apiKey,
["scope"] = "va_mitglied",
}));
// Antwort mit access_token, token_type und expires_in ausgeben
Console.WriteLine($"{(int)tokenResponse.StatusCode}: {await tokenResponse.Content.ReadAsStringAsync()}");
}
catch (Exception ex)
{
Console.WriteLine($"Fehler: {ex.Message}");
}
Console.Write("\nMit Enter beenden ...");
Console.ReadLine();
import { createInterface } from 'node:readline/promises';
// ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
// Tragen Sie hier Ihre Werte ein:
const clientId = '1234_mein_client';
const clientSecret = 'mein_secret';
const apiKey = 'mein_api_schluessel';
try {
// Token mit dem API-Schlüssel anfordern
const tokenResponse = await fetch('https://zugang.netxp-verein.de/connect/token', {
method: 'POST',
body: new URLSearchParams({
grant_type: 'api_key',
client_id: clientId,
client_secret: clientSecret,
apikey: apiKey,
scope: 'va_mitglied',
}),
});
// Antwort mit access_token, token_type und expires_in ausgeben
console.log(tokenResponse.status, await tokenResponse.text());
} catch (error) {
console.error('Fehler:', error instanceof Error ? error.message : error);
}
const rl = createInterface({ input: process.stdin, output: process.stdout });
await rl.question('\nMit Enter beenden ...');
rl.close();
<?php
// ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
// Tragen Sie hier Ihre Werte ein:
$clientId = '1234_mein_client';
$clientSecret = 'mein_secret';
$apiKey = 'mein_api_schluessel';
// Token mit dem API-Schlüssel anfordern
$ch = curl_init('https://zugang.netxp-verein.de/connect/token');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => http_build_query([
'grant_type' => 'api_key',
'client_id' => $clientId,
'client_secret' => $clientSecret,
'apikey' => $apiKey,
'scope' => 'va_mitglied',
]),
]);
$result = curl_exec($ch);
// Antwort mit access_token, token_type und expires_in ausgeben
echo $result === false ? 'Verbindungsfehler: ' . curl_error($ch) : $result, PHP_EOL;
echo PHP_EOL, 'Mit Enter beenden ...';
fgets(STDIN);
import requests
# ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
# Tragen Sie hier Ihre Werte ein:
CLIENT_ID = "1234_mein_client"
CLIENT_SECRET = "mein_secret"
API_KEY = "mein_api_schluessel"
try:
# Token mit dem API-Schlüssel anfordern
token_response = requests.post(
"https://zugang.netxp-verein.de/connect/token",
data={
"grant_type": "api_key",
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
"apikey": API_KEY,
"scope": "va_mitglied",
},
timeout=30,
)
# Antwort mit access_token, token_type und expires_in ausgeben
print(token_response.status_code, token_response.text)
except requests.RequestException as error:
print(f"Verbindungsfehler: {error}")
input("\nMit Enter beenden ...")
Mit Client Credentials (nur Verein-API)
Die Anwendung meldet sich als sie selbst an, nur mit Client-ID und Secret. Dieser Weg steht ausschließlich bei der Verein-API zur Verfügung. Der Zugriff erfolgt über einen von Netxp vorgegebenen Standardnutzer; bei Änderungen ist daher nicht erkennbar, welche Person sie veranlasst hat — siehe Wer meldet sich an?.
- CMD
- Bash
- C#
- TypeScript
- PHP
- Python
REM ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veroeffentlichen.
REM Tragen Sie hier Ihre Werte ein:
set "CLIENT_ID=1234_mein_client"
set "CLIENT_SECRET=mein_secret"
REM Token mit Client-ID und Secret (Client Credentials) anfordern und die Antwort ausgeben
powershell -NoProfile -Command "$body = @{grant_type='client_credentials'; client_id='%CLIENT_ID%'; client_secret='%CLIENT_SECRET%'; scope='va_mitglied'}; Invoke-RestMethod -Uri 'https://zugang.netxp-verein.de/connect/token' -Method Post -Body $body | ConvertTo-Json"
echo.
pause
# ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
# Tragen Sie hier Ihre Werte ein:
CLIENT_ID="1234_mein_client"
CLIENT_SECRET="mein_secret"
# Token mit Client-ID und Secret (Client Credentials) anfordern und die Antwort ausgeben
curl -s -X POST "https://zugang.netxp-verein.de/connect/token" \
--data-urlencode "grant_type=client_credentials" \
--data-urlencode "client_id=$CLIENT_ID" \
--data-urlencode "client_secret=$CLIENT_SECRET" \
--data-urlencode "scope=va_mitglied"
echo
read -r -p "Mit Enter beenden ..."
// ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
// Tragen Sie hier Ihre Werte ein:
var clientId = "1234_mein_client";
var clientSecret = "mein_secret";
try
{
using var http = new HttpClient();
// Token mit Client-ID und Secret (Client Credentials) anfordern
using var tokenResponse = await http.PostAsync(
"https://zugang.netxp-verein.de/connect/token",
new FormUrlEncodedContent(new Dictionary<string, string>
{
["grant_type"] = "client_credentials",
["client_id"] = clientId,
["client_secret"] = clientSecret,
["scope"] = "va_mitglied",
}));
// Antwort mit access_token, token_type und expires_in ausgeben
Console.WriteLine($"{(int)tokenResponse.StatusCode}: {await tokenResponse.Content.ReadAsStringAsync()}");
}
catch (Exception ex)
{
Console.WriteLine($"Fehler: {ex.Message}");
}
Console.Write("\nMit Enter beenden ...");
Console.ReadLine();
import { createInterface } from 'node:readline/promises';
// ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
// Tragen Sie hier Ihre Werte ein:
const clientId = '1234_mein_client';
const clientSecret = 'mein_secret';
try {
// Token mit Client-ID und Secret (Client Credentials) anfordern
const tokenResponse = await fetch('https://zugang.netxp-verein.de/connect/token', {
method: 'POST',
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: clientId,
client_secret: clientSecret,
scope: 'va_mitglied',
}),
});
// Antwort mit access_token, token_type und expires_in ausgeben
console.log(tokenResponse.status, await tokenResponse.text());
} catch (error) {
console.error('Fehler:', error instanceof Error ? error.message : error);
}
const rl = createInterface({ input: process.stdin, output: process.stdout });
await rl.question('\nMit Enter beenden ...');
rl.close();
<?php
// ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
// Tragen Sie hier Ihre Werte ein:
$clientId = '1234_mein_client';
$clientSecret = 'mein_secret';
// Token mit Client-ID und Secret (Client Credentials) anfordern
$ch = curl_init('https://zugang.netxp-verein.de/connect/token');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => http_build_query([
'grant_type' => 'client_credentials',
'client_id' => $clientId,
'client_secret' => $clientSecret,
'scope' => 'va_mitglied',
]),
]);
$result = curl_exec($ch);
// Antwort mit access_token, token_type und expires_in ausgeben
echo $result === false ? 'Verbindungsfehler: ' . curl_error($ch) : $result, PHP_EOL;
echo PHP_EOL, 'Mit Enter beenden ...';
fgets(STDIN);
import requests
# ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
# Tragen Sie hier Ihre Werte ein:
CLIENT_ID = "1234_mein_client"
CLIENT_SECRET = "mein_secret"
try:
# Token mit Client-ID und Secret (Client Credentials) anfordern
token_response = requests.post(
"https://zugang.netxp-verein.de/connect/token",
data={
"grant_type": "client_credentials",
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
"scope": "va_mitglied",
},
timeout=30,
)
# Antwort mit access_token, token_type und expires_in ausgeben
print(token_response.status_code, token_response.text)
except requests.RequestException as error:
print(f"Verbindungsfehler: {error}")
input("\nMit Enter beenden ...")
Login über Browser (eigene Oberflächen)
Für eigene Oberflächen, an denen sich Personen selbst anmelden, ist der Login über Browser der empfohlene Weg. Ihre Anwendung sieht das Passwort dabei nie.
- Die Anwendung leitet den Browser zur Authorization URL
https://zugang.netxp-verein.de/connect/authorizeweiter — mitclient_id,redirect_uri,response_type=code,scopeund den PKCE-Angabencode_challengeundcode_challenge_method=S256. - Die Person meldet sich auf der Anmeldeseite von Netxp-Verein an — als Mitglied mit E-Mail-Adresse und Passwort, als Vereinsbenutzer mit VereinsID, Benutzer und Passwort oder mit einem API-Schlüssel.
- Der Browser kehrt mit einem kurzlebigen Code zur
redirect_urizurück. - Die Anwendung tauscht den Code an der Token URL gegen das Access
Token (
grant_type=authorization_code).
Setzen Sie diesen Ablauf nicht selbst um, sondern verwenden Sie eine erprobte Bibliothek. Diese lesen alle Adressen selbstständig aus dem Discovery-Dokument:
| Sprache | Bibliothek (Beispiele) |
|---|---|
| C# | Microsoft.AspNetCore.Authentication.OpenIdConnect (ASP.NET Core) |
| TypeScript | oidc-client-ts |
| PHP | league/oauth2-client |
| Python | Authlib |
Im API-Client muss die Rücksprungadresse Ihrer Anwendung als Redirect-URI eingetragen sein. Läuft die Anwendung vollständig im Browser oder auf dem Smartphone, wählen Sie den Typ öffentlich — dann entfällt das Secret.
Die Token-Antwort
Bei Erfolg antwortet der Anmeldedienst mit einem JSON-Objekt (Beispielwerte):
{
"access_token": "eyJhbGciOiJSUzI1NiIs…",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "va_mitglied"
}
| Feld | Bedeutung |
|---|---|
access_token | Das Token für den Header Authorization: Bearer … |
token_type | Immer Bearer |
expires_in | Gültigkeit in Sekunden — standardmäßig 3600 (1 Stunde) |
scope | Die tatsächlich gewährten Scopes |
refresh_token | Nur vorhanden, wenn ein Refresh Token angefordert wurde (siehe unten) |
Tokens wiederverwenden und erneuern
- Wiederverwenden: Fordern Sie nicht für jeden Aufruf ein neues
Token an. Speichern Sie es zwischen und verwenden Sie es, bis es
kurz vor dem Ablauf steht (
expires_in). - Neu anfordern: Bei API-Schlüssel und Client Credentials fordern Sie nach Ablauf einfach ein neues Token an.
- Refresh Token: Bei Login über Browser und bei der
Passwort-Anmeldung kann die Anwendung ein Token ohne erneute Eingabe
der Anmeldedaten verlängern. Dafür muss im API-Client die
Zugriffsart Anmeldung automatisch verlängern (Refresh Token)
angekreuzt sein und die Anwendung bei der Anmeldung zusätzlich den
Scope
offline_accessanfordern — siehe Welche Scopes gibt es?. Die Token-Antwort enthält dann einrefresh_token:
- CMD
- Bash
- C#
- TypeScript
- PHP
- Python
REM ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veroeffentlichen.
REM Tragen Sie hier Ihre Werte ein:
set "CLIENT_ID=1234_mein_client"
set "CLIENT_SECRET=mein_secret"
set "REFRESH_TOKEN=refresh_token_aus_der_token_antwort"
REM Token mit dem Refresh Token anfordern und die Antwort ausgeben
powershell -NoProfile -Command "$body = @{grant_type='refresh_token'; client_id='%CLIENT_ID%'; client_secret='%CLIENT_SECRET%'; refresh_token='%REFRESH_TOKEN%'}; Invoke-RestMethod -Uri 'https://zugang.netxp-verein.de/connect/token' -Method Post -Body $body | ConvertTo-Json"
echo.
pause
# ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
# Tragen Sie hier Ihre Werte ein:
CLIENT_ID="1234_mein_client"
CLIENT_SECRET="mein_secret"
REFRESH_TOKEN="refresh_token_aus_der_token_antwort"
# Token mit dem Refresh Token anfordern und die Antwort ausgeben
curl -s -X POST "https://zugang.netxp-verein.de/connect/token" \
--data-urlencode "grant_type=refresh_token" \
--data-urlencode "client_id=$CLIENT_ID" \
--data-urlencode "client_secret=$CLIENT_SECRET" \
--data-urlencode "refresh_token=$REFRESH_TOKEN"
echo
read -r -p "Mit Enter beenden ..."
// ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
// Tragen Sie hier Ihre Werte ein:
var clientId = "1234_mein_client";
var clientSecret = "mein_secret";
var refreshToken = "refresh_token_aus_der_token_antwort";
try
{
using var http = new HttpClient();
// Token mit dem Refresh Token anfordern
using var tokenResponse = await http.PostAsync(
"https://zugang.netxp-verein.de/connect/token",
new FormUrlEncodedContent(new Dictionary<string, string>
{
["grant_type"] = "refresh_token",
["client_id"] = clientId,
["client_secret"] = clientSecret,
["refresh_token"] = refreshToken,
}));
// Antwort mit access_token, token_type und expires_in ausgeben
Console.WriteLine($"{(int)tokenResponse.StatusCode}: {await tokenResponse.Content.ReadAsStringAsync()}");
}
catch (Exception ex)
{
Console.WriteLine($"Fehler: {ex.Message}");
}
Console.Write("\nMit Enter beenden ...");
Console.ReadLine();
import { createInterface } from 'node:readline/promises';
// ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
// Tragen Sie hier Ihre Werte ein:
const clientId = '1234_mein_client';
const clientSecret = 'mein_secret';
const refreshToken = 'refresh_token_aus_der_token_antwort';
try {
// Token mit dem Refresh Token anfordern
const tokenResponse = await fetch('https://zugang.netxp-verein.de/connect/token', {
method: 'POST',
body: new URLSearchParams({
grant_type: 'refresh_token',
client_id: clientId,
client_secret: clientSecret,
refresh_token: refreshToken,
}),
});
// Antwort mit access_token, token_type und expires_in ausgeben
console.log(tokenResponse.status, await tokenResponse.text());
} catch (error) {
console.error('Fehler:', error instanceof Error ? error.message : error);
}
const rl = createInterface({ input: process.stdin, output: process.stdout });
await rl.question('\nMit Enter beenden ...');
rl.close();
<?php
// ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
// Tragen Sie hier Ihre Werte ein:
$clientId = '1234_mein_client';
$clientSecret = 'mein_secret';
$refreshToken = 'refresh_token_aus_der_token_antwort';
// Token mit dem Refresh Token anfordern
$ch = curl_init('https://zugang.netxp-verein.de/connect/token');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => http_build_query([
'grant_type' => 'refresh_token',
'client_id' => $clientId,
'client_secret' => $clientSecret,
'refresh_token' => $refreshToken,
]),
]);
$result = curl_exec($ch);
// Antwort mit access_token, token_type und expires_in ausgeben
echo $result === false ? 'Verbindungsfehler: ' . curl_error($ch) : $result, PHP_EOL;
echo PHP_EOL, 'Mit Enter beenden ...';
fgets(STDIN);
import requests
# ACHTUNG: Nur zum lokalen Testen! Zugangsdaten niemals weitergeben oder veröffentlichen.
# Tragen Sie hier Ihre Werte ein:
CLIENT_ID = "1234_mein_client"
CLIENT_SECRET = "mein_secret"
REFRESH_TOKEN = "refresh_token_aus_der_token_antwort"
try:
# Token mit dem Refresh Token anfordern
token_response = requests.post(
"https://zugang.netxp-verein.de/connect/token",
data={
"grant_type": "refresh_token",
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
"refresh_token": REFRESH_TOKEN,
},
timeout=30,
)
# Antwort mit access_token, token_type und expires_in ausgeben
print(token_response.status_code, token_response.text)
except requests.RequestException as error:
print(f"Verbindungsfehler: {error}")
input("\nMit Enter beenden ...")
Zugangsdaten sicher ablegen
Die Beispiele auf diesen Seiten enthalten die Zugangsdaten zum Ausprobieren direkt im Code. Für den dauerhaften Betrieb gehören Secret, API-Schlüssel und Passwörter nicht in den Quellcode, denn sie gewähren Zugriff auf die Daten Ihres Vereins. Geeignete Ablageorte sind:
- Umgebungsvariablen oder eine
.env-Datei, die in.gitignoreeingetragen ist - .NET: User Secrets für die Entwicklung, im Betrieb z. B. ein Schlüsseltresor (Azure Key Vault o. Ä.)
- WordPress: Konstanten in der
wp-config.phpstatt in Plugin- oder Theme-Einstellungen, die in der Datenbank landen
Alles, was im Browser oder in einer App beim Anwender läuft, ist für jeden einsehbar. Secret, API-Schlüssel und Passwörter gehören ausschließlich auf einen Server, den Sie kontrollieren. Anwendungen im Browser verwenden den Login über Browser mit einem öffentlichen API-Client.
Muss eine Anbindung sofort gestoppt werden — etwa weil Zugangsdaten in falsche Hände geraten sind —, löschen Sie den API-Client oder erzeugen Sie ein neues Secret. Das bisherige Secret wird nach kurzer Verzögerung ungültig. Siehe Reiter „Secret".
Token widerrufen
Beim Abmelden kann Ihre Anwendung ein Token aktiv ungültig machen. Dafür muss im API-Client unter Technische Details der Endpunkt Revocation angekreuzt sein.
curl -s -X POST "https://zugang.netxp-verein.de/connect/revocation" \
--data-urlencode "client_id=$CLIENT_ID" \
--data-urlencode "client_secret=$CLIENT_SECRET" \
--data-urlencode "token=$REFRESH_TOKEN" \
--data-urlencode "token_type_hint=refresh_token"
Browser-Anwendungen und CORS
Ruft eine Anwendung im Browser die MO-API oder VO-API direkt auf, muss ihre Adresse dort freigegeben sein (CORS). Netxp-Verein übernimmt diese Freigabe automatisch aus den Redirect- und Post-Logout-URIs der API-Clients. Tragen Sie die Adresse Ihrer Anwendung dort ein; die Freigabe wirkt nach einigen Minuten.
Verwandte Themen
- Übersicht — Verbindungsdaten und Scopes
- Schnellstart — vollständige Beispiele je Schnittstelle
- Fehlerbehandlung — Fehler bei Anmeldung und Aufruf
- API-Clients — Einrichtung des API-Clients