OBS/Kostenpflichtige Module/RESTServer/Scripting: Unterschied zwischen den Versionen

Aus OBS Wiki
Zur Navigation springen Zur Suche springen
(Die Seite wurde neu angelegt: „Photo Credіt rating Graphic Ƅy Flickr.com, courtesy of Gordana Adamοvic-Mladenovic Mom and dad ϲonsiderably hаve an effect on their children�s habits.<b…“)
 
Keine Bearbeitungszusammenfassung
 
(5 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
Photo Credіt rating Graphic Ƅy Flickr.com, courtesy of Gordana Adamοvic-Mladenovic Mom and dad ϲonsiderably hаve an effect on their children�s habits.<br>Children are like sponges--thеy product almоst everүthіng a guardian does and include what tҺey see into tҺeir individuɑl life. It is essential that dad and mom eѕtаblishеd the right illustrаtions fⲟr their kids. Detrimental illustrations can be harmful to a chilԁ�s advancement and can direct to undesirable habits.<br><br>No time to exercise routine? Master much more about LIVESTRONG.COM's nourishment and fitness apрⅼication! If yⲟu liked this article and you also would like to гecеive more info reǥarding [http://194.44.219.205/mediawiki/index.php/How_Consuming_Healthful_Harmful_Food_items_Impacts_Your_Body custom essay] i implore үou to viѕit the internet site. Socіal Expertise Rely Antisocial kids master their conduct from their parents� examρⅼes, according to research completed by the Coⅼlᥱge of Chicago revealed in the Јournal of Abnormal Kid Psychology.<br><br>Social abilіtieѕ can be interpreted as aⅼl the things from the standard well mannered �please� ɑnd �thank you� to speaking in entrance of crowds. Kids proɗuct their moms and dаdѕ and find out from them.<br><br>A Pressured-Out Legacy A parent�s reaction to prеssᥙre influencеs the way a child reacts to anxiety, states the web page More4Kidѕ. If a parent reacts negatively, a lіttle one will master to react negɑtively as well. In addition, adverse reactions to anxiety, this kind of as yelling and lashing out, can scare a kid.<br>Childrеn can master to shut them seⅼves down and may well even belieѵe that they are the induce of the tension. If pressure is taken care of positivеlʏ, it assists young children see that their paгents' aԀore for them never ever improvements, even when they are strеssed oսt.<br><br>Keᥱp Self-сontrol Positive The way a mother or father disciplines tremendously affects their chіldren's behavioг, as dеscribed on FamіⅼyDoctor.org. When a ⲣarent elects to use physical punishmеnt, these kinds of as spanking, it does not [http://www.magaltc.com educate] the little one how to alter his conduсt. Little oneѕ can also respond aggressively to bodily punishment.<br>When dad and mom chooses alternate soгts of ρunishment, these types of as time-outs, tһey arе serving to modіfy the child�s terrible actions in a quiet manner.<br><br>Fighting Frenzy If argսing among the motheгs and fathers is cоmpleted quite and with maturity, a kid can truly reward frοm seeing how confⅼictѕ are settled. Verbaⅼ and actսal physical fights are extremely difficult on children, warns the Youngster-Self-control-with-Adore web site. Young cһіldren might blame by themselves for their parents� argumentѕ and maу well be traumatizing for years tօ appear.<br>Children could develop minimal ѕelf-eѕteems and may well even behave violently towards other children. Dysfunctional families breed dysfunctional young children. Young children generally repeat this habits in their potential associаtions.<br><br>Child Abuse Deѕtroyѕ Boy or giгl аbuѕe triggers a range of antisocіal and destructive behaviors, in accordance to the web site HealthyPlace.com. This is simрly becauѕe abusеd youngsters try out to cope and to recognize why they arе ǥetting abused. Dad аnd mom who abuse tҺeir yoսng children could trigger their little ones to be intense аnd violent, expertise finding out complications and eᴠen turn into іnclսded in medicine or alcoholic beverages.<br><br>[https://En.wikipedia.org/wiki/Parents%27_Day Parents] who abuse present the reverse of what a kid demands to expand uр healthful. Rather, thеy damage the within and outsіde worⅼd of а boy or girl.
{{Kostenpflichtige Module}}
 
=Anleitung für Endpunkt-Skripte=
 
Jede Anfrage an einen Endpunkt wird nach erfolgreicher Authentifizierung und Autorisierung an das hinterlegte Skript weitergegeben. Das Skript ist in Object Pascal geschrieben und greift auf die OBS-Bibliothek (DB-Zugriff, Hilfsfunktionen) zu.
 
==Sicherheitshinweise==
 
{{Hinweis|Endpunkt-Skripte verarbeiten Daten aus dem Internet. Übergabeparameter dürfen niemals ungeprüft in SQL-Anweisungen eingebaut werden. Werte immer über ''DB_SQLVal'' bzw. Parameter-Bindings absichern, Eingabewerte gegen Whitelists prüfen.}}
 
* Eingaben gegen erwartete Werte prüfen (z.B. Pflichtfelder, erlaubte Typen, Wertebereiche).
* Nur das zurückgeben, was der Konsument wirklich braucht - keine internen IDs, keine Sys-Felder, keine Passwörter.
* Bei Fehlern keine internen Details an den Konsumenten zurückgeben; stattdessen schreibt der Server ohnehin Detail-Einträge in '''RESTSRV_PROTO'''.
 
==Methoden-Signatur==
 
Pro HTTP-Methode wird im Skript eine gleichnamige Funktion implementiert. Der Server ruft genau die Funktion auf, die zur Methode des eingehenden Requests passt.
 
function Get  (oParams: TStrings; oBody: TJSONObject): string;
function Post  (oParams: TStrings; oBody: TJSONObject): string;
function Put  (oParams: TStrings; oBody: TJSONObject): string;
function Delete(oParams: TStrings; oBody: TJSONObject): string;
function Patch (oParams: TStrings; oBody: TJSONObject): string;
 
Nicht implementierte Methoden liefern automatisch ''405''-ähnliche Fehler über die generische Skript-Antwort.
 
==Parameter==
 
===oParams (TStrings)===
 
Enthält alle Query-Parameter, POST-Parameter (form-urlencoded) sowie die durchgereichten HTTP-Header. Werte sind immer Strings.
 
Filterung durch den Server:
 
* Geblockte Header werden nicht durchgereicht: ''authorization'', ''cookie'', ''proxy-authorization'', ''x-forwarded-for'', ''x-real-ip'', ''apikey'', ''api_key''.
* Parameter mit Präfix '''_OBS_''' können von aussen nicht gesetzt werden; sie sind für interne Werte reserviert.
* Werte werden auf max. 1024 Zeichen begrenzt.
* Null-Bytes und Steuerzeichen (ausser Tab, CR, LF) werden entfernt.
 
Zugriff im Skript:
 
  if (not Empty(oParams.Values['kundennr'])) then begin
    cKundenNr := oParams.Values['kundennr'];
end;
 
===oBody (TJSONObject)===
 
Enthält den Request-Body, sofern dieser ein gültiges JSON-Objekt ist. Bei leerem oder nicht-JSON-Body wird ''nil'' übergeben.
 
cUser := '';
cPass := '';
if (Assigned(oBody)) then begin
    oVal := oBody.GetValue('username');
    if (Assigned(oVal)) then begin
        cUser := oVal.Value;
    end;
    oVal := oBody.GetValue('password');
    if (Assigned(oVal)) then begin
        cPass := oVal.Value;
    end;
end;
 
Maximale Body-Grösse: 10 MB.
 
===Reservierte _OBS_-Parameter===
 
Bei aktiver JWT-Authentifizierung stehen die Token-Claims als Parameter zur Verfügung:
 
{| class="wikitable"
! Parameter            !! Inhalt
|-
| _OBS_JWT_ID          || JWT-Id (''jti''-Claim) - typisch die User-Id
|-
| _OBS_JWT_SUBJECT    || Subject (''sub''-Claim) - typisch Benutzername
|-
| _OBS_JWT_AUDIENCE    || Audience (''aud''-Claim) - typisch Mandant / Rolle
|}
 
Diese Werte werden vom Server gesetzt und können vom Skript für Berechtigungs- und Mandantenprüfungen verwendet werden.
 
===Pfad-Parameter===
 
Stammt der Endpunkt aus einem Pfad-Template mit Platzhaltern (siehe [[OBS/Kostenpflichtige Module/RESTServer/Endpunkte|Endpunkte]]), stehen die aus den Platzhaltern erfassten Werte als reservierte Parameter mit Präfix '''_OBS_PATH_''' in ''oParams'' bereit:
 
{| class="wikitable"
! Template !! Zugriff im Skript
|-
| <code>/orders/{uid}</code> || ''oParams.Values['_OBS_PATH_uid']''
|-
| <code>/orders/{uid}/modules/{code}</code> || ''oParams.Values['_OBS_PATH_uid']'', ''oParams.Values['_OBS_PATH_code']''
|}
 
Da der Präfix ''_OBS_'' für von aussen gelieferte Header- und Query-Parameter gesperrt ist, sind diese Werte nicht durch den Client fälschbar. Ein vollständiges Beispiel zeigt [[OBS/Kostenpflichtige Module/RESTServer/Beispiel4|Beispiel 4 - Pfad-Parameter]].
 
==Rückgabe==
 
Die Rückgabe ist immer ein '''JSON-String'''. Wird ein leerer String zurückgegeben, antwortet der Server automatisch mit ''{}''. Der Server setzt Content-Type auf ''application/json; charset=utf-8'' und Status auf 200, sofern das Skript nicht selbst einen Fehler signalisiert.
 
Einfaches Beispiel:
 
<syntaxhighlight lang="pascal" line>
function Get(oParams: TStrings; oBody: TJSONObject): string;
var oRes: TJSONObject;
begin
    oRes := TJSONObject.Create();
    try
        oRes.AddPair('wert_string', '123');
        oRes.AddPair('wert_int'  , 456);
        result := oRes.ToJSON();
    finally
        MyFreeAndNil(oRes);
    end;
end;
</syntaxhighlight>
 
==JWT-Authentifizierungs-Skript==
 
Bei Zugängen mit aktiver JWT-Pflicht wird über den JWT-Endpunkt das im Zugang hinterlegte Authentifizierungs-Skript aufgerufen (F7 in der Zugänge-Liste). Das Skript muss eine Methode ''Authenticate'' bereitstellen:
 
<syntaxhighlight lang="pascal" line>
function Authenticate(oParams: TStrings; oBody: TJSONObject): string;
var oRes  : TJSONObject;
    cUser : string;
    cPass : string;
begin
    oRes := TJSONObject.Create();
    try
        // Eingangsdaten lesen (Body oder Query-Param)
        cUser := '';
        cPass := '';
        if (Assigned(oBody)) then begin
            oVal := oBody.GetValue('username');
            if (Assigned(oVal)) then begin
                cUser := oVal.Value;
            end;
            oVal := oBody.GetValue('password');
            if (Assigned(oVal)) then begin
                cPass := oVal.Value;
            end;
        end;
 
        // Prüfung gegen eigene Tabelle, Hash-Verfahren, LDAP, ...
        if (PasswortPasst(cUser, cPass)) then begin
            oRes.AddPair('status'          , 1);
            oRes.AddPair('_OBS_JWT_ID'    , cUser);
            oRes.AddPair('_OBS_JWT_SUBJECT', cUser);
            oRes.AddPair('_OBS_JWT_AUDIENCE', 'mandant1');
        end else begin
            oRes.AddPair('status', 9);
            oRes.AddPair('error' , 'Login fehlgeschlagen');
        end;
 
        result := oRes.ToJSON();
    finally
        MyFreeAndNil(oRes);
    end;
end;
</syntaxhighlight>
 
Rückgabewerte:
 
{| class="wikitable"
! status !! Bedeutung
|-
| 1      || Erfolgreich, der Server erzeugt aus den ''_OBS_JWT_*''-Werten einen Token (HS256)
|-
| 9      || Misserfolg, der Server antwortet mit 403 und protokolliert den Wert von ''error''
|}
 
==Fehlerbehandlung im Skript==
 
Tritt im Skript eine Exception auf oder schlägt die Syntax-Prüfung fehl, antwortet der Server mit 500 ''Interner Fehler'' und protokolliert die Detail-Meldung in '''RESTSRV_PROTO''' (mit Skript-Fehlertext). Der Konsument sieht keine internen Details.
 
Will das Skript einen spezifischen Fehler an den Konsumenten zurückgeben, ist eine eigene JSON-Struktur zu liefern:
 
<syntaxhighlight lang="pascal" line>
function Post(oParams: TStrings; oBody: TJSONObject): string;
var oRes: TJSONObject;
begin
    oRes := TJSONObject.Create();
    try
        if (Empty(oParams.Values['kundennr'])) then begin
            oRes.AddPair('status', 'error');
            oRes.AddPair('msg'  , 'Parameter ''kundennr'' fehlt');
            result := oRes.ToJSON();
            exit;
        end;
        // ...
    finally
        MyFreeAndNil(oRes);
    end;
end;
</syntaxhighlight>
 
==Skript-Cache==
 
Der Server cached das kompilierte Skript pro Endpunkt (Schlüssel: ''sys_date'' des Endpunkts). Zusätzlich werden die Endpunkt-Definitionen pro Server-Profil in einem TTL-Cache (Standard 60 s) gehalten. Eine Skript-Änderung über F7 wird daher erst nach Ablauf dieses TTL (bzw. nach einer Cache-Invalidierung) wirksam - typischerweise innerhalb einer Minute, nicht zwingend sofort.
 
==Verfügbare Bibliotheken==
 
Im Skript können alle OBS-Standard-Bibliotheken verwendet werden. Typische Einstiegspunkte:
 
* ''Base.Tools'' - String-, Datum-, IIF-, Empty-Helper
* ''Base.DB'' / ''Base.xQuery'' - Datenbank-Operationen, ''DB_SQLVal'', ''DB_SOpen'', ''DB_LSeek''
* ''Base.qSqlReg'' - ''qSqlInit'', ''qSet'', ''SaveData''
* ''System.JSON'' - JSON-Objekte und -Arrays
* ''Base.ToolsConst'' - Konstanten wie ''CRLF'', ''SINGELQUOTE'', ''EMPTY_DATE''
 
Konkrete Beispiele:
 
* [[OBS/Kostenpflichtige Module/RESTServer/Beispiel1|Beispiel: Daten-Abruf mit JWT]]
* [[OBS/Kostenpflichtige Module/RESTServer/Beispiel2|Beispiel: Datensatz anlegen mit JSON-Body]]
* [[OBS/Kostenpflichtige Module/RESTServer/Beispiel4|Beispiel: Pfad-Parameter im Routing]]

Aktuelle Version vom 15. Juni 2026, 08:24 Uhr

Kostenpflichtige Module

Internet-Shop
UPS
IMS Professional
SMS
Mehrlager-Verwaltung
Mehrsprachen Modul
Multilanguage Modul
EVA Marketing Tool
Termin-Projekte
Edifact-Schnittstelle
Backup Überwachung Email
OBS Geo Daten
DeliSprint / DPD
Filialen
Cashback
Moebelschnittstelle
Dokumenten Manager
DocuWare-Schnittstelle
OFML-Kalkulation
Versicherungsschaden
Gutschriftsanzeigen
Kameraverwaltung
DataInOut
OpenMasterData / IDS
Sammelpositionen


Anleitung für Endpunkt-Skripte

Jede Anfrage an einen Endpunkt wird nach erfolgreicher Authentifizierung und Autorisierung an das hinterlegte Skript weitergegeben. Das Skript ist in Object Pascal geschrieben und greift auf die OBS-Bibliothek (DB-Zugriff, Hilfsfunktionen) zu.

Sicherheitshinweise

HINWEIS: Endpunkt-Skripte verarbeiten Daten aus dem Internet. Übergabeparameter dürfen niemals ungeprüft in SQL-Anweisungen eingebaut werden. Werte immer über DB_SQLVal bzw. Parameter-Bindings absichern, Eingabewerte gegen Whitelists prüfen.
  • Eingaben gegen erwartete Werte prüfen (z.B. Pflichtfelder, erlaubte Typen, Wertebereiche).
  • Nur das zurückgeben, was der Konsument wirklich braucht - keine internen IDs, keine Sys-Felder, keine Passwörter.
  • Bei Fehlern keine internen Details an den Konsumenten zurückgeben; stattdessen schreibt der Server ohnehin Detail-Einträge in RESTSRV_PROTO.

Methoden-Signatur

Pro HTTP-Methode wird im Skript eine gleichnamige Funktion implementiert. Der Server ruft genau die Funktion auf, die zur Methode des eingehenden Requests passt.

function Get   (oParams: TStrings; oBody: TJSONObject): string;
function Post  (oParams: TStrings; oBody: TJSONObject): string;
function Put   (oParams: TStrings; oBody: TJSONObject): string;
function Delete(oParams: TStrings; oBody: TJSONObject): string;
function Patch (oParams: TStrings; oBody: TJSONObject): string;

Nicht implementierte Methoden liefern automatisch 405-ähnliche Fehler über die generische Skript-Antwort.

Parameter

oParams (TStrings)

Enthält alle Query-Parameter, POST-Parameter (form-urlencoded) sowie die durchgereichten HTTP-Header. Werte sind immer Strings.

Filterung durch den Server:

  • Geblockte Header werden nicht durchgereicht: authorization, cookie, proxy-authorization, x-forwarded-for, x-real-ip, apikey, api_key.
  • Parameter mit Präfix _OBS_ können von aussen nicht gesetzt werden; sie sind für interne Werte reserviert.
  • Werte werden auf max. 1024 Zeichen begrenzt.
  • Null-Bytes und Steuerzeichen (ausser Tab, CR, LF) werden entfernt.

Zugriff im Skript:

if (not Empty(oParams.Values['kundennr'])) then begin
    cKundenNr := oParams.Values['kundennr'];
end;

oBody (TJSONObject)

Enthält den Request-Body, sofern dieser ein gültiges JSON-Objekt ist. Bei leerem oder nicht-JSON-Body wird nil übergeben.

cUser := ;
cPass := ;
if (Assigned(oBody)) then begin
    oVal := oBody.GetValue('username');
    if (Assigned(oVal)) then begin
        cUser := oVal.Value;
    end;
    oVal := oBody.GetValue('password');
    if (Assigned(oVal)) then begin
        cPass := oVal.Value;
    end;
end;

Maximale Body-Grösse: 10 MB.

Reservierte _OBS_-Parameter

Bei aktiver JWT-Authentifizierung stehen die Token-Claims als Parameter zur Verfügung:

Parameter Inhalt
_OBS_JWT_ID JWT-Id (jti-Claim) - typisch die User-Id
_OBS_JWT_SUBJECT Subject (sub-Claim) - typisch Benutzername
_OBS_JWT_AUDIENCE Audience (aud-Claim) - typisch Mandant / Rolle

Diese Werte werden vom Server gesetzt und können vom Skript für Berechtigungs- und Mandantenprüfungen verwendet werden.

Pfad-Parameter

Stammt der Endpunkt aus einem Pfad-Template mit Platzhaltern (siehe Endpunkte), stehen die aus den Platzhaltern erfassten Werte als reservierte Parameter mit Präfix _OBS_PATH_ in oParams bereit:

Template Zugriff im Skript
/orders/{uid} oParams.Values['_OBS_PATH_uid']
/orders/{uid}/modules/{code} oParams.Values['_OBS_PATH_uid'], oParams.Values['_OBS_PATH_code']

Da der Präfix _OBS_ für von aussen gelieferte Header- und Query-Parameter gesperrt ist, sind diese Werte nicht durch den Client fälschbar. Ein vollständiges Beispiel zeigt Beispiel 4 - Pfad-Parameter.

Rückgabe

Die Rückgabe ist immer ein JSON-String. Wird ein leerer String zurückgegeben, antwortet der Server automatisch mit {}. Der Server setzt Content-Type auf application/json; charset=utf-8 und Status auf 200, sofern das Skript nicht selbst einen Fehler signalisiert.

Einfaches Beispiel:

function Get(oParams: TStrings; oBody: TJSONObject): string;
var oRes: TJSONObject;
begin
    oRes := TJSONObject.Create();
    try
        oRes.AddPair('wert_string', '123');
        oRes.AddPair('wert_int'   , 456);
        result := oRes.ToJSON();
    finally
        MyFreeAndNil(oRes);
    end;
end;

JWT-Authentifizierungs-Skript

Bei Zugängen mit aktiver JWT-Pflicht wird über den JWT-Endpunkt das im Zugang hinterlegte Authentifizierungs-Skript aufgerufen (F7 in der Zugänge-Liste). Das Skript muss eine Methode Authenticate bereitstellen:

function Authenticate(oParams: TStrings; oBody: TJSONObject): string;
var oRes  : TJSONObject;
    cUser : string;
    cPass : string;
begin
    oRes := TJSONObject.Create();
    try
        // Eingangsdaten lesen (Body oder Query-Param)
        cUser := '';
        cPass := '';
        if (Assigned(oBody)) then begin
            oVal := oBody.GetValue('username');
            if (Assigned(oVal)) then begin
                cUser := oVal.Value;
            end;
            oVal := oBody.GetValue('password');
            if (Assigned(oVal)) then begin
                cPass := oVal.Value;
            end;
        end;

        // Prüfung gegen eigene Tabelle, Hash-Verfahren, LDAP, ...
        if (PasswortPasst(cUser, cPass)) then begin
            oRes.AddPair('status'          , 1);
            oRes.AddPair('_OBS_JWT_ID'     , cUser);
            oRes.AddPair('_OBS_JWT_SUBJECT', cUser);
            oRes.AddPair('_OBS_JWT_AUDIENCE', 'mandant1');
        end else begin
            oRes.AddPair('status', 9);
            oRes.AddPair('error' , 'Login fehlgeschlagen');
        end;

        result := oRes.ToJSON();
    finally
        MyFreeAndNil(oRes);
    end;
end;

Rückgabewerte:

status Bedeutung
1 Erfolgreich, der Server erzeugt aus den _OBS_JWT_*-Werten einen Token (HS256)
9 Misserfolg, der Server antwortet mit 403 und protokolliert den Wert von error

Fehlerbehandlung im Skript

Tritt im Skript eine Exception auf oder schlägt die Syntax-Prüfung fehl, antwortet der Server mit 500 Interner Fehler und protokolliert die Detail-Meldung in RESTSRV_PROTO (mit Skript-Fehlertext). Der Konsument sieht keine internen Details.

Will das Skript einen spezifischen Fehler an den Konsumenten zurückgeben, ist eine eigene JSON-Struktur zu liefern:

function Post(oParams: TStrings; oBody: TJSONObject): string;
var oRes: TJSONObject;
begin
    oRes := TJSONObject.Create();
    try
        if (Empty(oParams.Values['kundennr'])) then begin
            oRes.AddPair('status', 'error');
            oRes.AddPair('msg'   , 'Parameter ''kundennr'' fehlt');
            result := oRes.ToJSON();
            exit;
        end;
        // ...
    finally
        MyFreeAndNil(oRes);
    end;
end;

Skript-Cache

Der Server cached das kompilierte Skript pro Endpunkt (Schlüssel: sys_date des Endpunkts). Zusätzlich werden die Endpunkt-Definitionen pro Server-Profil in einem TTL-Cache (Standard 60 s) gehalten. Eine Skript-Änderung über F7 wird daher erst nach Ablauf dieses TTL (bzw. nach einer Cache-Invalidierung) wirksam - typischerweise innerhalb einer Minute, nicht zwingend sofort.

Verfügbare Bibliotheken

Im Skript können alle OBS-Standard-Bibliotheken verwendet werden. Typische Einstiegspunkte:

  • Base.Tools - String-, Datum-, IIF-, Empty-Helper
  • Base.DB / Base.xQuery - Datenbank-Operationen, DB_SQLVal, DB_SOpen, DB_LSeek
  • Base.qSqlReg - qSqlInit, qSet, SaveData
  • System.JSON - JSON-Objekte und -Arrays
  • Base.ToolsConst - Konstanten wie CRLF, SINGELQUOTE, EMPTY_DATE

Konkrete Beispiele: