[{"data":1,"prerenderedAt":1270},["ShallowReactive",2],{"blog-de-supabase-users-logged-out":3,"blog-index-de":741},{"id":4,"title":5,"body":6,"category":700,"cover":701,"coverAlt":702,"description":703,"draft":704,"extension":705,"faq":706,"image":722,"keywords":723,"meta":730,"navigation":731,"ogTitle":5,"path":732,"published":733,"seo":734,"stem":735,"tldr":736,"updated":733,"__hash__":740},"blog_de\u002Fblog\u002Fsupabase-users-logged-out.md","Supabase \"Invalid Refresh Token: Refresh Token Not Found\": 3 Ursachen",{"type":7,"value":8,"toc":685},"minimark",[9,13,24,27,35,40,43,62,84,110,114,117,126,217,225,229,232,238,260,266,270,291,294,297,303,306,311,315,327,340,358,363,369,373,376,398,412,415,419,425,428,432,451,454,512,519,525,528,532,535,562,571,577,581,584,593,611,620,640,644,679],[10,11,12],"p",{},"Deine Nutzer schreiben dir, dass sie abgemeldet wurden. Einer war mitten in\neinem Formular, und eine andere ist sicher, dass sie nichts gedrückt hat. Wenn du\ndie App selbst ausprobierst, läuft sie. Dann öffnest du deine Logs und findest\nimmer wieder dieselbe Zeile:",[14,15,20],"pre",{"className":16,"code":18,"language":19},[17],"language-text","AuthApiError: Invalid Refresh Token: Refresh Token Not Found\n","text",[21,22,18],"code",{"__ignoreMap":23},"",[10,25,26],{},"Supabase \"Invalid Refresh Token: Refresh Token Not Found\" ist Supabase Auth, der\nTeil von Supabase, der Leute anmeldet, und er sagt damit: Zu dem Token, das deine\nApp geschickt hat, um eine Sitzung am Laufen zu halten, gibt es keinen Eintrag.\nWeil nichts mehr zu verlängern ist, meldet deine App den Nutzer ab.",[10,28,29,30,34],{},"Hier ist der Teil, den man leicht verkehrt herum versteht: ",[31,32,33],"strong",{},"Dieser Fehler ist\nder letzte Schritt, und die Ursache lag früher."," Wenn Supabase das Token nicht\nmehr findet, ist die Sitzung, zu der es gehörte, schon vorbei. Beendet hat sie\neine Abmeldung, ein Token, das zweimal kam, oder ein Limit, das jemand gesetzt\nhat. Ein länger gültiges Access Token oder das Abschalten der Prüfung, die eine\nSitzung beendet, macht die Zeile in deinen Logs seltener und lässt die Ursache\ngenau, wo sie war.",[36,37,39],"h2",{"id":38},"was-bedeutet-invalid-refresh-token-refresh-token-not-found","Was bedeutet \"Invalid Refresh Token: Refresh Token Not Found\"?",[10,41,42],{},"Es bedeutet, dass Supabase Auth ein Refresh Token bekommen hat, zu dem es keinen\nEintrag hat, und die Sitzung deshalb nicht verlängert hat.",[10,44,45,46,49,50,53,54,61],{},"Jeder angemeldete Nutzer hat zwei Tokens. Das ",[31,47,48],{},"Access Token"," funktioniert wie\nein Armband: Es weist ihn eine kurze Zeit lang aus, eine Stunde, solange du die\nEinstellung nicht geändert hast, und deine App zeigt es bei jeder Anfrage vor.\nDas ",[31,51,52],{},"Refresh Token"," ist ein Ticket. Bevor das Armband abläuft, bringt deine App\ndas Ticket zum Schalter, und dieser Schalter ist Supabase Auth. Dort tauscht sie\nes gegen ein neues Armband und ein neues Ticket. Supabases\n",[55,56,60],"a",{"href":57,"rel":58},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fauth\u002Fsessions",[59],"nofollow","Anleitung zu Sitzungen"," sagt,\ndass Refresh Tokens \"never expire but can only be used once\".",[10,63,64,67,68,71,72,77,78,83],{},[21,65,66],{},"Refresh Token Not Found"," heißt, dass der Schalter ein Ticket nachschlägt und\nnichts findet. Der Server antwortet mit HTTP 400 und dem Code\n",[21,69,70],{},"refresh_token_not_found",", den Supabases\n",[55,73,76],{"href":74,"rel":75},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fauth\u002Fdebugging\u002Ferror-codes",[59],"Liste der Auth-Fehlercodes","\nals \"Session containing the refresh token not found.\" beschreibt. Ist auch das\nArmband abgelaufen, entfernt\n",[55,79,82],{"href":80,"rel":81},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fsupabase-js\u002Fblob\u002Fmaster\u002Fpackages\u002Fcore\u002Fauth-js\u002Fsrc\u002FGoTrueClient.ts",[59],"Supabases JavaScript-Client","\ndie Sitzung aus dem Browser und teilt deiner App mit, dass sich der Nutzer\nabgemeldet hat. In diesem Moment sieht dein Nutzer die Anmeldeseite.",[10,85,86,87,91,92,95,96,100,101,104,105,109],{},"Keins der beiden Tokens ist einer der API-Schlüssel deines Projekts, die sind\neine eigene Frage:\n",[55,88,90],{"href":89},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","welche davon in deine App gehören",".\nSteht in deiner Meldung stattdessen ",[21,93,94],{},"Invalid JWT",", wurde das Armband abgelehnt\nund nicht das Ticket, und\n",[55,97,99],{"href":98},"\u002Fblog\u002Fsupabase-invalid-jwt","dieser Fehler hat eine eigene Seite",".\nKommt die Person danach nicht wieder hinein und das Anmeldeformular sagt\n",[21,102,103],{},"Invalid login credentials",",\n",[55,106,108],{"href":107},"\u002Fblog\u002Fsupabase-invalid-login","stecken hinter dieser Meldung drei verschiedene Fälle",".",[36,111,113],{"id":112},"warum-werden-meine-supabase-nutzer-abgemeldet","Warum werden meine Supabase-Nutzer abgemeldet?",[10,115,116],{},"Weil die Sitzung hinter ihrem Ticket geendet hat und das Armband, das sie noch\ntragen, sie angemeldet hielt, bis es ablief. Diese Verzögerung, mit der\nStandardeinstellung bis zu einer Stunde, lässt die Abmeldungen zufällig wirken:\nDer Nutzer fliegt eine Weile nach dem Ende der Sitzung raus.",[10,118,119,120,125],{},"Supabase Auth hat vier Arten zu sagen, dass ein Ticket nicht gilt, und jede zeigt\nauf eine andere Ursache. Das sind die genauen Meldungen aus\n",[55,121,124],{"href":122,"rel":123},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fauth\u002Fblob\u002Fmaster\u002Finternal\u002Ftokens\u002Fservice.go",[59],"dem Code des Supabase-Auth-Servers",":",[127,128,129,145],"table",{},[130,131,132],"thead",{},[133,134,135,139,142],"tr",{},[136,137,138],"th",{},"Die Meldung in deinem Log",[136,140,141],{},"Der Code",[136,143,144],{},"Was passiert ist",[146,147,148,163,178,202],"tbody",{},[133,149,150,156,160],{},[151,152,153],"td",{},[21,154,155],{},"Invalid Refresh Token: Refresh Token Not Found",[151,157,158],{},[21,159,70],{},[151,161,162],{},"Der Schalter hat keinen Eintrag zu diesem Ticket. Eine Abmeldung hat seine Sitzung beendet, oder es wurde vor so langer Zeit getauscht, dass sein Eintrag weg ist.",[133,164,165,170,175],{},[151,166,167],{},[21,168,169],{},"Invalid Refresh Token: Already Used",[151,171,172],{},[21,173,174],{},"refresh_token_already_used",[151,176,177],{},"Das Ticket wurde vor mehr als zehn Sekunden getauscht und kommt wieder. Supabase beendet dann die ganze Sitzung.",[133,179,180,194,199],{},[151,181,182,185,186,189,190,193],{},[21,183,184],{},"Invalid Refresh Token: Session Expired",", manchmal mit ",[21,187,188],{},"(Inactivity)"," oder ",[21,191,192],{},"(Revoked by Newer Login)"," dahinter",[151,195,196],{},[21,197,198],{},"session_expired",[151,200,201],{},"Ein Sitzungslimit in deinen Auth-Einstellungen hat sie beendet.",[133,203,204,209,214],{},[151,205,206],{},[21,207,208],{},"Invalid Refresh Token: No Valid Session Found",[151,210,211],{},[21,212,213],{},"session_not_found",[151,215,216],{},"Die Sitzung, zu der das Ticket gehörte, gibt es nicht mehr.",[10,218,219,220,224],{},"Hinter diesen Meldungen stehen drei Ursachen, in Supabases eigener Dokumentation\nund in den Berichten auf seinen Issue-Trackern, und jede hat ihre eigene Lösung.\nKann sich niemand mehr anmelden oder ist die ganze App leer, hast du ein anderes\nProblem, und\n",[55,221,223],{"href":222},"\u002Fblog\u002Fis-supabase-down-or-your-app","ist Supabase down, oder ist es deine App","\nist der richtige Anfang.",[36,226,228],{"id":227},"ein-refresh-token-funktioniert-einmal","Ein Refresh Token funktioniert einmal",[10,230,231],{},"Jedes Mal, wenn deine App eine Sitzung verlängert, gibt sie das Ticket ab, und\nder Schalter zerreißt das alte. Supabase nennt das Refresh Token Rotation. Das\nalte Ticket funktioniert noch zehn Sekunden weiter, was die Anleitung zu\nSitzungen das Reuse Interval nennt, damit sich ein Server und ein Browser, die\nfast im selben Moment verlängern, nicht gegenseitig rauswerfen. Auch ein Client,\nder sein Ticket getauscht und die Antwort über eine schlechte Verbindung\nverloren hat, ist abgedeckt: Er bekommt das aktuelle Ticket zurück.",[10,233,234,235,109],{},"Außerhalb dieser beiden Fälle gilt ein altes Ticket, das zurückkommt, als\nWarnzeichen, denn ein Token, das zweimal auftaucht, sieht aus wie ein gestohlenes.\nDie Anleitung sagt, dass die ganze Sitzung dann \"is regarded as terminated and\nall refresh tokens belonging to it are marked as revoked\". Die Antwort lautet\ndiesmal ",[21,236,237],{},"Already Used",[10,239,240,241,243,244,247,248,253,254,256,257,259],{},"Ein weiterer Schritt macht aus ",[21,242,237],{}," ein ",[21,245,246],{},"Not Found",". Der\nSupabase-Auth-Server\n",[55,249,252],{"href":250,"rel":251},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fauth\u002Fblob\u002Fmaster\u002Finternal\u002Fmodels\u002Fcleanup.go",[59],"löscht die Einträge zerrissener Tickets","\n24 Stunden, nachdem sie widerrufen wurden. Das veraltete Ticket, das heute\n",[21,255,237],{}," bekommt, bekommt also morgen ",[21,258,66],{},", weil der\nSchalter keinen Eintrag mehr hat, mit dem er es vergleichen könnte.",[261,262],"diagram",{"alt":263,"caption":264,"src":265},"Ein Zeitstrahl für ein Ticket. Zuerst wird es am Schalter gegen ein neues Armband und ein neues Ticket getauscht, und das alte wird zerrissen. Innerhalb von 10 Sekunden noch einmal vorgezeigt, wird es noch angenommen. Später am selben Tag wird es als schon benutzt abgelehnt. Nach 24 Stunden hat das Buch des Schalters eine leere Zeile, wo sein Eintrag war.","Ein Ticket zu vier Zeitpunkten. Innerhalb von zehn Sekunden funktioniert es noch. Danach wird es als schon benutzt abgelehnt, und sobald sein Eintrag einen Tag später gelöscht ist, findet der Schalter es gar nicht mehr.","\u002Fblog\u002Fsupabase-users-logged-out\u002Fone-ticket-four-moments-1600x700.png",[36,267,269],{"id":268},"ursache-1-jemand-hat-sich-abgemeldet-auf-diesem-gerät-oder-einem-anderen","Ursache 1: Jemand hat sich abgemeldet, auf diesem Gerät oder einem anderen",[10,271,272,273,276,277,280,281,286,287,290],{},"Eine Abmeldung löscht die Sitzung auf der Seite des Schalters, und jedes Ticket\ndaraus wird eins, das der Schalter nicht findet. In Supabases JavaScript-Client\nbeendet ",[21,274,275],{},"signOut()"," ohne etwas in den Klammern ",[31,278,279],{},"jede"," Sitzung dieses Nutzers,\nauf jedem Gerät. Supabases\n",[55,282,285],{"href":283,"rel":284},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fauth\u002Fsignout",[59],"Anleitung zum Abmelden"," sagt das\nausdrücklich: Mit dieser Voreinstellung scheitern die anderen Sitzungen mit\n",[21,288,289],{},"AuthApiError: Invalid Refresh Token: Refresh Token Not Found",", sobald sie das\nnächste Mal verlängern wollen, \"even though no one signed out on that device.\"",[10,292,293],{},"Ein Nutzer, der sich auf dem Handy abmeldet, ist also auch auf dem Laptop\nabgemeldet, bis zu einer Stunde später, wenn das Armband des Laptops abläuft und\nsein Ticket als unbekannt zurückkommt. Von seinem Platz aus sieht es so aus, als\nhätte deine App ihn ohne Grund rausgeworfen.",[10,295,296],{},"Soll jedes Gerät für sich angemeldet bleiben, darf der Abmeldeaufruf nur die\nSitzung beenden, aus der er kommt:",[14,298,301],{"className":299,"code":300,"language":19},[17],"await supabase.auth.signOut({ scope: 'local' })\n",[21,302,300],{"__ignoreMap":23},[10,304,305],{},"Bitte deinen Builder, diese Form überall zu verwenden, wo deine App Leute\nabmeldet. Der andere gewöhnliche Weg, eine Sitzung zu beenden, ist eine\nPasswortänderung, die Supabases Anleitung zu Sitzungen zu den Dingen zählt, die\neine Sitzung beenden.",[261,307],{"alt":308,"caption":309,"src":310},"Zwei Felder. Im linken meldet sich ein Handy mit signOut() ab, und die Tickets von Handy, Laptop und Tablet sind alle zerrissen. Im rechten meldet sich das Handy mit scope local ab, und nur das Ticket des Handys ist zerrissen, Laptop und Tablet behalten ihre.","Ohne scope beendet eine Abmeldung die Sitzung auf jedem Gerät. Mit scope local beendet sie nur die auf dem Gerät in deiner Hand.","\u002Fblog\u002Fsupabase-users-logged-out\u002Fone-sign-out-every-device-1600x720.png",[36,312,314],{"id":313},"ursache-2-das-neue-ticket-ist-nie-im-browser-angekommen","Ursache 2: Das neue Ticket ist nie im Browser angekommen",[10,316,317,318,321,322,324,325,109],{},"Rendert deine App Seiten auf einem Server, wie es eine Next.js-App tut, dann\nverlängert auch dieser Server Sitzungen. Er liest das Ticket aus einem Cookie,\ntauscht es am Schalter und muss das neue Ticket in einem ",[21,319,320],{},"Set-Cookie","-Header\nseiner Antwort an den Browser zurückschicken. Kommt dieses Cookie nicht an,\nbehält der Browser das alte Ticket, und die nächste Anfrage zeigt ein Ticket vor,\ndas der Server schon getauscht hat. Innerhalb von zehn Sekunden geht das durch.\nDanach heißt es ",[21,323,237],{}," und die Sitzung endet, und einen Tag später ist\ndasselbe Ticket ",[21,326,246],{},[10,328,329,330,335,336,339],{},"Supabases\n",[55,331,334],{"href":332,"rel":333},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fauth\u002Fserver-side\u002Fcreating-a-client",[59],"Anleitung zum Erstellen eines Server-Clients","\nnennt den Fehler, der das in einer Next.js-App auslöst. Der Code, der die Sitzung\nverlängert und den Next.js 16 Proxy nennt und frühere Versionen Middleware, muss\ndie Antwort zurückgeben, in die die neuen Cookies geschrieben wurden: \"An earlier\nresponse doesn't carry the refreshed cookies, so the user is signed out on the\nnext request.\" Dieselbe Anleitung warnt, dass unter Next.js 15 und früher eine\nDatei namens ",[21,337,338],{},"proxy.ts"," gar nicht ausgeführt wird, \"so sessions never refresh and\nusers get signed out\". Ein Assistent, der mit der neuesten Dokumentation arbeitet,\nkann genau diese Datei in eine ältere App schreiben.",[10,341,342,343,351,352,357],{},"Supabases Anleitung sagt auch, warum sich dieser Fall schwer finden lässt: \"it\nlooks like users being signed out at random rather than an error in your code.\"\nDie Berichte klingen genauso. Ein Entwickler schrieb auf dem\n",[55,344,347,348],{"href":345,"rel":346},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fssr\u002Fissues\u002F68",[59],"Issue-Tracker von ",[21,349,350],{},"@supabase\u002Fssr","\n\"I'm inadvertently logged out of my web application every day\", und der\nSupabase-Entwickler, der antwortete, verwies darauf, wie die Middleware ihre\nAntwort weitergab. Der\n",[55,353,356],{"href":354,"rel":355},"https:\u002F\u002Fgithub.com\u002Fsupabase\u002Fsupabase-swift\u002Fissues\u002F486",[59],"Bericht zu einer iOS-App","\nbeschreibt die Abmeldung \"2-3 days after logging in\" und wurde geschlossen,\nnachdem Updates an Supabases Swift-Bibliothek die Meldungen seltener gemacht\nhatten.",[261,359],{"alt":360,"caption":361,"src":362},"Ein Browser schickt sein Ticket an einen Server. Der Server tauscht es am Schalter und bekommt ein neues zurück. Die Antwort, die das neue Ticket zum Browser bringen soll, bricht ab, bevor sie ankommt, also schickt der Browser das alte Ticket noch einmal, und der Schalter lehnt es als schon benutzt ab.","Der Server hat die Sitzung verlängert, und das neue Ticket ist nie zurückgekommen. Der Browser hält noch das, das schon getauscht wurde.","\u002Fblog\u002Fsupabase-users-logged-out\u002Fnew-ticket-lost-1600x640.png",[10,364,365,366,368],{},"Zum Prüfen öffnest du die Entwicklertools deines Browsers auf einer Seite, die\ndie Sitzung verlängert hat, und siehst dir die Antwort im Tab Network an. Sie\nsollte ein ",[21,367,320],{}," mit dem neuen Token tragen, und die nächste Anfrage\nsollte genau dieses Token zurückschicken.",[36,370,372],{"id":371},"ursache-3-ein-sitzungslimit-in-deinen-auth-einstellungen","Ursache 3: ein Sitzungslimit in deinen Auth-Einstellungen",[10,374,375],{},"Ab dem Pro-Plan kann Supabase Sitzungen absichtlich beenden, über die Seite\nSessions in den Auth-Einstellungen deines Projekts. Es gibt drei Limits, und die\nAnleitung zu Sitzungen beschreibt jedes:",[377,378,379,386,392],"ul",{},[380,381,382,385],"li",{},[31,383,384],{},"Zeitlich begrenzte Sitzungen"," enden nach einer festen Zeit, egal wie aktiv\nder Nutzer ist.",[380,387,388,391],{},[31,389,390],{},"Ein Inaktivitäts-Timeout"," beendet eine Sitzung, die eine Weile nicht\nverlängert wurde.",[380,393,394,397],{},[31,395,396],{},"Eine Sitzung pro Nutzer"," behält nur die neueste Anmeldung, also beendet eine\nAnmeldung auf dem Handy die Sitzung auf dem Laptop.",[10,399,400,401,404,405,189,407,409,410,109],{},"Diese sagen es in ihrer eigenen Meldung, ",[21,402,403],{},"Session Expired",", beim zweiten und\ndritten mit ",[21,406,188],{},[21,408,192],{}," dahinter. Die\nAnleitung ergänzt, dass beendete Sitzungen 24 Stunden später gelöscht werden.\nEin Ticket aus einer solchen Sitzung, das danach zurückkommt, bekommt also\nstattdessen ",[21,411,246],{},[10,413,414],{},"Hast du eins davon eingestellt, sind die Abmeldungen die Einstellung bei der\nArbeit. War es nicht so gemeint, oder hat eine Vorlage oder ein Assistent es für\ndich eingestellt, zeigt die Seite, welches Limit an ist.",[36,416,418],{"id":417},"der-fall-der-harmlos-ist","Der Fall, der harmlos ist",[10,420,421,422,424],{},"Ein Ticket aus einer schon beendeten Sitzung, das aus einem alten Tab kommt oder\naus einem Browser, den wochenlang niemand geöffnet hat, bekommt auch\n",[21,423,66],{},". Die Person dahinter war schon abgemeldet. Ihr Browser\nhat einmal gefragt, Supabase hat nein gesagt, und sie sieht deine Anmeldeseite,\ndie sie ohnehin gesehen hätte.",[10,426,427],{},"Im Log sieht das so aus: eine Zeile für einen Nutzer, oft kurz nachdem sich\ndieser Nutzer irgendwo abgemeldet hat, und danach nichts mehr von ihm. Solche\nZeilen sind der Fehler, der seine Arbeit macht. Verfolgen solltest du dieselben\nLeute immer wieder, oder viele verschiedene Leute am selben Tag.",[36,429,431],{"id":430},"so-liest-du-deine-auth-logs-dafür","So liest du deine Auth-Logs dafür",[10,433,434,435,438,439,442,443,446,447,450],{},"Öffne ",[31,436,437],{},"Logs"," in deinem Supabase-Dashboard, wähle den Log-Typ ",[31,440,441],{},"Auth"," und\ndurchsuche die Event-Meldungen nach ",[21,444,445],{},"refresh token",". Wähl eine Zeile aus, um ihre\nDetails zu sehen, darunter die ID des Nutzers, und der Filter ",[31,448,449],{},"User"," grenzt die\nListe dann auf diese eine Person ein. Wie weit die Logs zurückreichen, hängt von\ndeinem Plan ab, also lies sie, solange die Beschwerden frisch sind.",[10,452,453],{},"Dann lies, was sich wiederholt:",[127,455,456,466],{},[130,457,458],{},[133,459,460,463],{},[136,461,462],{},"Was du im Auth-Log siehst",[136,464,465],{},"Worauf es hinweist",[146,467,468,479,489,502],{},[133,469,470,476],{},[151,471,472,473,475],{},"Ein ",[21,474,66],{}," für einen Nutzer, und danach nichts",[151,477,478],{},"Ein alter Tab oder ein zurückkehrender Browser. Harmlos.",[133,480,481,486],{},[151,482,483,485],{},[21,484,66],{}," für einen Nutzer kurz nach seiner Abmeldung woanders",[151,487,488],{},"Ursache 1, eine Abmeldung, die jedes Gerät beendet hat",[133,490,491,499],{},[151,492,493,495,496,498],{},[21,494,237],{},", einen Tag später ",[21,497,66],{},", für dieselben Nutzer, immer wieder",[151,500,501],{},"Ursache 2, neue Tickets, die nicht im Browser ankommen",[133,503,504,509],{},[151,505,506,508],{},[21,507,403],{},", mit einem Grund in Klammern",[151,510,511],{},"Ursache 3, ein Sitzungslimit",[10,513,514,515,518],{},"Du kannst auch die Datenbank fragen, wie oft sich Leute anmelden. Jede Anmeldung\nlegt eine Zeile in ",[21,516,517],{},"auth.sessions"," an, und eine Abmeldung löscht sie. Füg das in\nden SQL Editor ein:",[14,520,523],{"className":521,"code":522,"language":19},[17],"select user_id, count(*) as sessions, max(created_at) as latest\nfrom auth.sessions\nwhere created_at > now() - interval '14 days'\ngroup by user_id\norder by sessions desc\nlimit 20;\n",[21,524,522],{"__ignoreMap":23},[10,526,527],{},"Ein Nutzer mit viel mehr Sitzungen, als er Geräte hat, hat sich immer wieder\nangemeldet, ohne sich je abzumelden, und genau das tut jemand, den deine App\nständig rauswirft.",[36,529,531],{"id":530},"was-du-beim-beheben-nicht-ändern-solltest","Was du beim Beheben nicht ändern solltest",[10,533,534],{},"Deine Regeln für Row Level Security, die Reuse Detection und die Gültigkeit des\nAccess Tokens. Alle drei sehen aus wie eine Lösung und lassen die Ursache, wo sie\nist, und die erste zu lockern kann deine Daten für Fremde öffnen.",[10,536,537,540,541,544,545,550,551,553,554,557,558,109],{},[31,538,539],{},"Lass deine Regeln für Row Level Security in Ruhe."," Row Level Security sind die\nRegeln, die entscheiden, welche Zeilen jeder Besucher bekommt. Solange Nutzer\nrausfliegen, bleibt jeder Bildschirm, dessen Regel ",[21,542,543],{},"auth.uid()"," liest, für sie\nleer, denn laut\n",[55,546,549],{"href":547,"rel":548},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fdatabase\u002Fpostgres\u002Frow-level-security",[59],"Supabases Dokumentation","\ngibt ",[21,552,543],{}," ",[21,555,556],{},"null"," zurück, wenn die Sitzung abgelaufen ist. Die\nnaheliegende Lösung ist, diese Regel zu lockern, bis sich der Bildschirm wieder\nfüllt, und dann füllt er sich auch für Fremde. Hat das schon jemand getan, fragt\nunser kostenloser Scan jede Tabelle, die deine App nennt, wie viele Zeilen ein\nBesucher ohne Anmeldung bekäme, liest die Zahl, ohne eine einzige Zeile abzurufen,\nund braucht ungefähr 20 Sekunden ohne Konto:\n",[55,559,561],{"href":560},"\u002Fsecurity-scanner","scanne deine App",[10,563,564,567,568,570],{},[31,565,566],{},"Lass die Reuse Detection eingeschaltet."," Supabase lässt dich sie abschalten,\nin den erweiterten Einstellungen auf der Seite Sessions, und nennt das \"generally\nnot recommended\". Ist sie aus, liefert Ursache 2 kein ",[21,569,237],{}," mehr, und\ndas neue Ticket kommt trotzdem nie im Browser an.",[10,572,573,576],{},[31,574,575],{},"Lass das Access Token bei einer Stunde."," Ein längeres Armband schiebt die\nAbmeldung auf und lässt ihre Ursache, wo sie ist. Supabases Anleitung sagt, dass\nein Wert über einer Stunde \"generally discouraged for security reasons\" ist.",[36,578,580],{"id":579},"damit-anmeldungen-nach-der-lösung-halten","Damit Anmeldungen nach der Lösung halten",[10,582,583],{},"Zwei Dinge können noch schiefgehen, wenn die Abmeldungen aufhören: Eine spätere\nÄnderung bringt sie zurück, und eine unterwegs gelockerte Regel lässt eine\nTabelle für Fremde offen.",[10,585,586],{},[31,587,588,592],{},[55,589,591],{"href":590},"\u002Fwebsite-monitoring","Reeve Monitor"," prüft weiter von außen:",[377,594,595,598,601,608],{},[380,596,597],{},"ob deine App erreichbar ist, jede Minute geprüft, damit eine Welle von \"Ich wurde abgemeldet\"-Nachrichten nicht für einen Ausfall gehalten wird",[380,599,600],{},"die vollständige Sicherheitsprüfung jede Stunde, für bis zu drei Apps",[380,602,603,604,607],{},"eine Nachricht, wenn sich ein Ergebnis ",[31,605,606],{},"ändert",", damit eine beim Beheben gelockerte Regel nicht wartet, bis du hinschaust",[380,609,610],{},"ein monatlicher Bericht in einfacher Sprache über das, was er gesehen hat",[10,612,613],{},[31,614,615,619],{},[55,616,618],{"href":617},"\u002Fsupabase-backups","Reeve Care"," hält eine Kopie deiner Supabase-Datenbank:",[377,621,622,625,628,631,634,637],{},[380,623,624],{},"eine verschlüsselte Kopie nach Zeitplan, auf Reeves eigenem Speicher in der EU, außerhalb deines Supabase-Kontos",[380,626,627],{},"das Auth-Schema, in dem die Konten deiner Nutzer liegen, damit sie mit allem anderen zurückkommen",[380,629,630],{},"jede Kopie geprüft, bevor sie zählt, durch Zählen der Zeilen in jeder Tabelle",[380,632,633],{},"auch deine hochgeladenen Dateien, sobald du einen Storage-Zugang verbindest",[380,635,636],{},"eine Wiederherstellung per Klick, mit einer Sicherheitskopie des aktuellen Stands vorab",[380,638,639],{},"alles, was Monitor tut",[36,641,643],{"id":642},"was-du-jetzt-tun-solltest","Was du jetzt tun solltest",[645,646,647],"key-takeaways",{},[377,648,649,655,661,667,670,673],{},[380,650,651,652,654],{},"Durchsuch deine Auth-Logs nach ",[21,653,445],{}," und lies, welche Meldung sich wiederholt, und bei wem.",[380,656,657,658,109],{},"Beendet eine Abmeldung auf einem Gerät die anderen, ändere sie auf ",[21,659,660],{},"signOut({ scope: 'local' })",[380,662,663,664,666],{},"Rendert deine App auf einem Server, sorg dafür, dass die Antwort, die eine Sitzung verlängert hat, auch die ist, die beim Browser ankommt, und prüf ihr ",[21,665,320],{}," im Tab Network.",[380,668,669],{},"Sieh auf der Seite Sessions deiner Auth-Einstellungen nach einer Zeitbegrenzung, einem Inaktivitäts-Timeout oder einer Sitzung pro Nutzer, die niemand einschalten wollte.",[380,671,672],{},"Lass Row Level Security, die Reuse Detection und die Gültigkeit des Access Tokens, wie sie sind, solange du das behebst.",[380,674,675,676,678],{},"Behandle ein ",[21,677,246],{}," pro Nutzer als Rauschen und dieselben Nutzer jeden Tag als Fehler.",[10,680,681,682,684],{},"Fang mit dem Auth-Log an, denn die Meldung, die sich wiederholt, sagt dir, welche\nder drei Ursachen du hast. Dann, sobald die Leute angemeldet bleiben,\n",[55,683,561],{"href":560},", um zu prüfen, dass unterwegs nichts\ngelockert wurde.",{"title":23,"searchDepth":686,"depth":686,"links":687},3,[688,690,691,692,693,694,695,696,697,698,699],{"id":38,"depth":689,"text":39},2,{"id":112,"depth":689,"text":113},{"id":227,"depth":689,"text":228},{"id":268,"depth":689,"text":269},{"id":313,"depth":689,"text":314},{"id":371,"depth":689,"text":372},{"id":417,"depth":689,"text":418},{"id":430,"depth":689,"text":431},{"id":530,"depth":689,"text":531},{"id":579,"depth":689,"text":580},{"id":642,"depth":689,"text":643},"Sicherheitsgrundlagen","\u002Fblog\u002Fsupabase-users-logged-out\u002Fcover-1200x630.png","Ein Ticket, in zwei Teile gerissen, die linke Hälfte hell, die rechte blass und im Fallen, vor einer Reihe ganzer Tickets.","Supabase \"Invalid Refresh Token: Refresh Token Not Found\" meldet deine Nutzer ab. Drei Ursachen, und wie das Auth-Log sie trennt.",false,"md",[707,710,713,716,719],{"q":708,"a":709},"Warum werden meine Supabase-Nutzer scheinbar zufällig abgemeldet?","Weil die Sitzung hinter ihrem Refresh Token geendet hat und das Access Token, das sie noch haben, sie bis zu einer Stunde lang angemeldet hält. Die Abmeldung kommt also später als ihre Ursache. Die üblichen Gründe sind eine Abmeldung auf einem anderen Gerät, ein erneuertes Token, das nie im Browser angekommen ist, und ein Sitzungslimit in deinen Auth-Einstellungen. Das Auth-Log zeigt, welcher es ist.",{"q":711,"a":712},"Was ist ein Refresh Token?","Es ist die langlebige Hälfte einer Supabase-Sitzung. Das Access Token weist den Nutzer standardmäßig eine Stunde lang aus, und bevor es abläuft, tauscht deine App das Refresh Token gegen ein neues Paar. Jedes Refresh Token funktioniert einmal, und das alte hört zehn Sekunden nach dem Tausch auf zu funktionieren.",{"q":714,"a":715},"Ist \"Refresh Token Not Found\" ein Zeichen für einen Angriff?","Für sich genommen nicht. Es heißt, dass Supabase Auth ein Token abgelehnt hat, von dem es keinen Eintrag hat, und das ist die richtige Antwort. Gegen ein gestohlenes Token schützt die Reuse Detection, die eine Sitzung beendet, wenn ein altes Token zurückkommt, und Supabase empfiehlt, sie eingeschaltet zu lassen.",{"q":717,"a":718},"Warum passiert das nur in Produktion?","Weil die meisten Ursachen Zeit oder ein zweites Gerät brauchen. Ein veraltetes Token wird am ersten Tag als schon benutzt abgelehnt und als nicht gefunden, sobald sein Eintrag einen Tag später gelöscht ist, und eine Sitzung, mit der du beim Bauen angemeldet bist, lebt selten so lange. Echte Nutzer melden sich außerdem auf mehreren Geräten an, und dort zeigt sich eine Abmeldung, die jede Sitzung beendet.",{"q":720,"a":721},"Wie lange hält eine Supabase-Sitzung?","Standardmäßig, bis sich der Nutzer abmeldet. Das Access Token hält eine Stunde, wenn du es nicht änderst, und das Refresh Token läuft nie ab, funktioniert aber nur einmal. Ab dem Pro-Plan kannst du Sitzungen nach Gesamtdauer, nach Inaktivität oder auf eine pro Nutzer begrenzen, auf der Seite Sessions deiner Auth-Einstellungen.","\u002Fblog\u002Fsupabase-users-logged-out\u002Fcard-800x500.png",[724,725,70,726,727,728,729],"invalid refresh token refresh token not found","supabase invalid refresh token","supabase nutzer werden abgemeldet","supabase refresh token already used","supabase session expired","supabase ssr refresh token fehler",{},true,"\u002Fblog\u002Fsupabase-users-logged-out","2026-10-19",{"title":5,"description":703},"blog\u002Fsupabase-users-logged-out",[737,738,739],"Supabase \"Invalid Refresh Token: Refresh Token Not Found\" heißt: Supabase Auth kennt das Refresh Token nicht, das deine App geschickt hat. Die Sitzung lässt sich nicht verlängern, und der Nutzer wird abgemeldet.","Drei Dinge löschen diesen Eintrag: eine Abmeldung (die in JavaScript standardmäßig jedes Gerät beendet), ein schon benutztes Token, das ein zweites Mal kommt, und ein Sitzungslimit in deinen Auth-Einstellungen.","Manches davon ist eine harmlose Zeile aus einem alten Tab. Manches meldet jeden Tag alle Nutzer ab. Das Auth-Log zeigt dir, was davon, und jede Ursache hat ihre eigene Lösung.","dxe3VWLK9e2NtrY45pfcoeehEWyD_V_uMEBxsNO9Tfg",[742,748,754,760,766,772,778,784,790,796,802,809,815,820,826,832,838,844,850,856,862,868,869,875,881,886,892,898,904,910,916,922,928,934,940,946,952,958,964,970,975,981,987,993,999,1005,1010,1016,1022,1028,1034,1040,1046,1052,1058,1064,1070,1076,1082,1088,1094,1100,1106,1112,1118,1124,1130,1136,1142,1148,1154,1160,1166,1172,1178,1184,1190,1196,1202,1208,1214,1220,1226,1232,1237,1243,1249,1255,1260,1266],{"path":743,"title":744,"description":745,"published":746,"category":700,"image":747,"draft":704},"\u002Fblog\u002Fmax-client-connections-reached","Supabase \"max client connections reached\" erklärt","Supabase \"max client connections reached\": Der Pooler hat keinen Platz für noch einen Client. Der Port in deinem Connection String setzt das Limit.","2026-11-09","\u002Fblog\u002Fmax-client-connections-reached\u002Fcard-800x500.png",{"path":749,"title":750,"description":751,"published":752,"category":700,"image":753,"draft":704},"\u002Fblog\u002Funsupported-provider-provider-is-not-enabled","Supabase-Fehler: \"Unsupported provider: provider is not enabled\"","\"Unsupported provider: provider is not enabled\" heißt: Google-Login ist in deinem Supabase-Projekt aus. Die Lösung, und was bei redirect_uri_mismatch hilft.","2026-11-08","\u002Fblog\u002Funsupported-provider-provider-is-not-enabled\u002Fcard-800x500.png",{"path":755,"title":756,"description":757,"published":758,"category":700,"image":759,"draft":704},"\u002Fblog\u002Fviolates-foreign-key-constraint","Supabase-Fehler \"violates foreign key constraint\" beim Einfügen","Supabase \"insert or update on table violates foreign key constraint\": Deine Zeile zeigt auf eine, die es nicht gibt. Welche, warum, und die Lösung.","2026-11-07","\u002Fblog\u002Fviolates-foreign-key-constraint\u002Fcard-800x500.png",{"path":761,"title":762,"description":763,"published":764,"category":700,"image":765,"draft":704},"\u002Fblog\u002Fnull-value-violates-not-null-constraint","Supabase-Fehler \"null value in column violates not-null constraint\"","Supabase \"null value in column violates not-null constraint\": Eine Pflichtspalte kam leer an. Woher die Null kommt, und die Lösung.","2026-11-06","\u002Fblog\u002Fnull-value-violates-not-null-constraint\u002Fcard-800x500.png",{"path":767,"title":768,"description":769,"published":770,"category":700,"image":771,"draft":704},"\u002Fblog\u002Fauth-session-missing","Supabase \"Auth session missing!\": wo die Sitzung geblieben ist","\"Auth session missing!\" heißt: supabase-js fand keine angemeldete Sitzung und fragte Supabase gar nicht erst. Wo die Sitzung blieb, und die Lösung je Fall.","2026-11-05","\u002Fblog\u002Fauth-session-missing\u002Fcard-800x500.png",{"path":773,"title":774,"description":775,"published":776,"category":700,"image":777,"draft":704},"\u002Fblog\u002Finvalid-claim-missing-sub-claim","Supabase \"invalid claim: missing sub claim\": niemand ist angemeldet","\"invalid claim: missing sub claim\" heißt: Supabase Auth bekam ein echtes Token ohne Nutzer darin, deinen Projektschlüssel statt einer Sitzung.","2026-11-04","\u002Fblog\u002Finvalid-claim-missing-sub-claim\u002Fcard-800x500.png",{"path":779,"title":780,"description":781,"published":782,"category":700,"image":783,"draft":704},"\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function","\"Failed to send a request to the Edge Function\": der echte Grund","\"Failed to send a request to the Edge Function\" heißt: Der Browser hat keine lesbare Antwort bekommen. Seine Konsole sagt, warum, und ob deine Funktion lief.","2026-11-03","\u002Fblog\u002Ffailed-to-send-a-request-to-the-edge-function\u002Fcard-800x500.png",{"path":785,"title":786,"description":787,"published":788,"category":700,"image":789,"draft":704},"\u002Fblog\u002Fsupabase-auth-redirects-to-localhost","Warum Supabase-E-Mail-Links auf localhost:3000 weiterleiten","Leitet Supabase auf localhost:3000 um, ist die Site URL unverändert, oder deine Adresse fehlt in Redirect URLs. Die Lösung und der Platzhalter, den du meidest.","2026-11-02","\u002Fblog\u002Fsupabase-auth-redirects-to-localhost\u002Fcard-800x500.png",{"path":791,"title":792,"description":793,"published":794,"category":700,"image":795,"draft":704},"\u002Fblog\u002Femail-link-is-invalid-or-has-expired","Supabase \"Email link is invalid or has expired\" bei einem neuen Link","Bei einem Link von vor einer Minute heißt Supabases \"Email link is invalid or has expired\" meist: Ein Mailfilter hat ihn zuerst benutzt. Prüfen und beheben.","2026-11-01","\u002Fblog\u002Femail-link-is-invalid-or-has-expired\u002Fcard-800x500.png",{"path":797,"title":798,"description":799,"published":800,"category":700,"image":801,"draft":704},"\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout","Supabase \"canceling statement due to statement timeout\" erklärt","Supabase \"canceling statement due to statement timeout\": Eine Abfrage lief länger als ihre Rolle darf, 3 Sekunden für Besucher. Prüf zuerst die RLS-Regel.","2026-10-31","\u002Fblog\u002Fcanceling-statement-due-to-statement-timeout\u002Fcard-800x500.png",{"path":803,"title":804,"description":805,"published":806,"category":807,"image":808,"draft":704},"\u002Fblog\u002Fdatabase-error-deleting-user","\"Database error deleting user\" in Supabase und was mitgelöscht wird","\"Database error deleting user\" in Supabase heißt: Deine Datenbank hat das Löschen abgelehnt. Der Grund steht im Log, die Lösung entscheidet, was mitgeht.","2026-10-30","Backups","\u002Fblog\u002Fdatabase-error-deleting-user\u002Fcard-800x500.png",{"path":810,"title":811,"description":812,"published":813,"category":700,"image":814,"draft":704},"\u002Fblog\u002Fstripe-webhook-no-signatures-found","\"No signatures found matching the expected signature\" bei Supabase","Ein Stripe-Webhook in einer Supabase Edge Function meldet \"No signatures found matching the expected signature\"? Zwei Ursachen. Prüfe weiter.","2026-10-29","\u002Fblog\u002Fstripe-webhook-no-signatures-found\u002Fcard-800x500.png",{"path":107,"title":816,"description":817,"published":818,"category":700,"image":819,"draft":704},"\"Invalid login credentials\" in Supabase: die drei Ursachen","Supabase sagt \"Invalid login credentials\" bei falschem Passwort, unbekannter E-Mail und Google-Konto. So erkennst du, welcher Fall es ist.","2026-10-28","\u002Fblog\u002Fsupabase-invalid-login\u002Fcard-800x500.png",{"path":821,"title":822,"description":823,"published":824,"category":700,"image":825,"draft":704},"\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code","\"Edge Function returned a non-2xx status code\": der echte Fehler","\"Edge Function returned a non-2xx status code\" heißt: Deine Supabase-Funktion hat mit einem Fehler geantwortet. So liest du den echten.","2026-10-27","\u002Fblog\u002Fedge-function-returned-a-non-2xx-status-code\u002Fcard-800x500.png",{"path":827,"title":828,"description":829,"published":830,"category":700,"image":831,"draft":704},"\u002Fblog\u002Fcertificate-not-trusted","Zertifikat nicht vertrauenswürdig: drei Ursachen außer Ablauf","Zertifikat nicht vertrauenswürdig, obwohl das Datum stimmt? Es nennt eine andere Adresse, hat sich selbst signiert oder seiner Kette fehlt ein Glied.","2026-10-26","\u002Fblog\u002Fcertificate-not-trusted\u002Fcard-800x500.png",{"path":833,"title":834,"description":835,"published":836,"category":700,"image":837,"draft":704},"\u002Fblog\u002Finvalid-input-syntax-for-type-uuid","Supabase \"invalid input syntax for type uuid\": was im Zitat steht","Supabase \"invalid input syntax for type uuid\" heißt: Deine App hat etwas geschickt, das keine ID ist. Zitat lesen, Abfrage zurückhalten, Spalte behalten.","2026-10-25","\u002Fblog\u002Finvalid-input-syntax-for-type-uuid\u002Fcard-800x500.png",{"path":839,"title":840,"description":841,"published":842,"category":700,"image":843,"draft":704},"\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint","Supabase \"duplicate key value violates unique constraint\" erklärt","Supabase \"duplicate key value violates unique constraint\" heißt: Der Wert ist schon vergeben. Spalte finden, Lösung wählen, Wert vom Bildschirm fernhalten.","2026-10-24","\u002Fblog\u002Fduplicate-key-value-violates-unique-constraint\u002Fcard-800x500.png",{"path":845,"title":846,"description":847,"published":848,"category":700,"image":849,"draft":704},"\u002Fblog\u002Fsupabase-relation-does-not-exist","Supabase \"relation does not exist\", obwohl die Tabelle da ist","Supabase \"relation does not exist\" oder PGRST205: Keine Tabelle passt zu Name und Schema deiner Abfrage. Vier Prüfungen, und was eine Freigabe öffnet.","2026-10-23","\u002Fblog\u002Fsupabase-relation-does-not-exist\u002Fcard-800x500.png",{"path":851,"title":852,"description":853,"published":854,"category":700,"image":855,"draft":704},"\u002Fblog\u002Fsupabase-function-not-found","Supabase PGRST202: \"Could not find the function in the schema cache\"","Supabase \"Could not find the function in the schema cache\" nennt die Argumente, die deine App geschickt hat. Vergleich sie mit der Funktion.","2026-10-22","\u002Fblog\u002Fsupabase-function-not-found\u002Fcard-800x500.png",{"path":857,"title":858,"description":859,"published":860,"category":700,"image":861,"draft":704},"\u002Fblog\u002Fsupabase-schema-cache-column-error","Supabase PGRST204: \"Could not find the column in the schema cache\"","Supabase \"Could not find the column in the schema cache\" heißt meist: Der Name passt nicht. Vier Prüfungen und der Einzeiler zum Neuladen.","2026-10-21","\u002Fblog\u002Fsupabase-schema-cache-column-error\u002Fcard-800x500.png",{"path":863,"title":864,"description":865,"published":866,"category":700,"image":867,"draft":704},"\u002Fblog\u002Fsupabase-email-rate-limit-exceeded","Supabase \"Email Rate Limit Exceeded\": zwei Limits, ein Fehlercode","Supabase \"Email Rate Limit Exceeded\" begrenzt jede E-Mail deines Projekts: 2 pro Stunde beim eingebauten Absender. Was zählt und wie du es anhebst.","2026-10-20","\u002Fblog\u002Fsupabase-email-rate-limit-exceeded\u002Fcard-800x500.png",{"path":732,"title":5,"description":703,"published":733,"category":700,"image":722,"draft":704},{"path":870,"title":871,"description":872,"published":873,"category":700,"image":874,"draft":704},"\u002Fblog\u002Fpermission-denied-for-schema-public","Supabase \"permission denied for schema public\": drei Ursachen","Supabase \"permission denied for schema public\" heißt: Ein Grant auf das Schema fehlt. Was ihn entfernt hat und welche Zeile ihn zurückbringt.","2026-10-18","\u002Fblog\u002Fpermission-denied-for-schema-public\u002Fcard-800x500.png",{"path":876,"title":877,"description":878,"published":879,"category":700,"image":880,"draft":704},"\u002Fblog\u002Fsupabase-bucket-not-found","Supabase \"Bucket not found\": die drei Dinge, die es bedeutet","Supabase \"Bucket not found\" ist eins von drei Dingen: ein öffentlicher Link zu einem privaten Bucket, ein ungenauer Name oder das falsche Projekt.","2026-10-17","\u002Fblog\u002Fsupabase-bucket-not-found\u002Fcard-800x500.png",{"path":98,"title":882,"description":883,"published":884,"category":700,"image":885,"draft":704},"Supabase invalid JWT: Welcher Schlüssel streikt hier?","Ein Supabase invalid JWT ist PGRST301: ein signiertes Token hat die Prüfung nicht bestanden. In neueren Projekten ist das die Sitzung, nicht der API-Schlüssel.","2026-10-16","\u002Fblog\u002Fsupabase-invalid-jwt\u002Fcard-800x500.png",{"path":887,"title":888,"description":889,"published":890,"category":700,"image":891,"draft":704},"\u002Fblog\u002Fsupabase-single-row-error","Supabase \"multiple (or no) rows returned\" heißt meist: keine Zeilen","Supabase gibt PGRST116 zurück, \"JSON object requested, multiple (or no) rows returned\", wenn die Abfrage nichts fand. Versteckte Zeilen wirken fehlend.","2026-10-15","\u002Fblog\u002Fsupabase-single-row-error\u002Fcard-800x500.png",{"path":893,"title":894,"description":895,"published":896,"category":700,"image":897,"draft":704},"\u002Fblog\u002Fdatabase-error-saving-new-user","\"Database error saving new user\" in Supabase: wo du nachsiehst","\"Database error saving new user\" heißt: etwas an deiner Supabase-Registrierung ist fehlgeschlagen. Der echte Fehler steht in deinen Logs.","2026-10-14","\u002Fblog\u002Fdatabase-error-saving-new-user\u002Fcard-800x500.png",{"path":899,"title":900,"description":901,"published":902,"category":700,"image":903,"draft":704},"\u002Fblog\u002Fwhat-is-supabase","Was ist Supabase? Die Datenbank, die dein Builder ausgesucht hat","Was ist Supabase: die Datenbank, der Login und der Dateispeicher hinter deiner App. Supabase betreibt die Server, die Regeln zu deinen Zeilen gehören dir.","2026-10-13","\u002Fblog\u002Fwhat-is-supabase\u002Fcard-800x500.png",{"path":905,"title":906,"description":907,"published":908,"category":700,"image":909,"draft":704},"\u002Fblog\u002Faws-access-key-exposed-in-frontend","Ein offengelegter AWS-Schlüssel im Frontend ist kein OpenAI-Key","Ein im Frontend offengelegter AWS-Zugriffsschlüssel liest und schreibt deinen Speicher. Die Lösung ist meist eine presigned URL, kein neuer Schlüssel.","2026-10-12","\u002Fblog\u002Faws-access-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":911,"title":912,"description":913,"published":914,"category":700,"image":915,"draft":704},"\u002Fblog\u002Fstorage-upload-violates-row-level-security","\"Row-level security policy for table objects\" beim Upload","\"New row violates row-level security policy for table objects\" heißt: Deinem Upload fehlt eine insert-Regel. Ein öffentlicher Bucket fügt keine hinzu.","2026-10-11","\u002Fblog\u002Fstorage-upload-violates-row-level-security\u002Fcard-800x500.png",{"path":917,"title":918,"description":919,"published":920,"category":700,"image":921,"draft":704},"\u002Fblog\u002Fbase44-security-scan","Base44 Security Scan: das, was nur er sehen kann","Der Base44 Security Scan prüft sieben Arten von Problemen von innen. Hier ist die Hälfte, die er liest und sonst niemand, und die Hälfte, die er nie ansieht.","2026-10-10","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":923,"title":924,"description":925,"published":926,"category":700,"image":927,"draft":704},"\u002Fblog\u002Fapi-key-leaked-what-to-do","Dein API-Key wurde geleakt. Die richtige Reihenfolge","Ein API-Key wurde geleakt und du weißt nicht, was zuerst zu tun ist. Nicht jeder Key im Frontend ist ein Leck, und die Reihenfolge zählt mehr als das Tempo.","2026-10-09","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",{"path":929,"title":930,"description":931,"published":932,"category":700,"image":933,"draft":704},"\u002Fblog\u002Finfinite-recursion-in-policy-for-relation","\"Infinite recursion detected in policy\" ohne RLS abzuschalten","\"Infinite recursion detected in policy for relation\" heißt: Deine Policy hat die Tabelle gefragt, die sie schützt. So brichst du den Kreis.","2026-10-08","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fcard-800x500.png",{"path":935,"title":936,"description":937,"published":938,"category":700,"image":939,"draft":704},"\u002Fblog\u002Fno-api-key-found-in-request","\"No API key found in request\" in Supabase, und die falsche Lösung","\"No API key found in request\" heißt, deine Supabase-Anfrage kam ohne Schlüssel an. Die meisten Antworten zeigen stattdessen auf deine Datenbankregeln.","2026-10-07","\u002Fblog\u002Fno-api-key-found-in-request\u002Fcard-800x500.png",{"path":941,"title":942,"description":943,"published":944,"category":700,"image":945,"draft":704},"\u002Fblog\u002Fis-base44-safe","Ist Base44 sicher? Was 5.442 echte Base44-Apps zeigten","Ist Base44 sicher? Wir haben 5.442 laufende Base44-Apps mit neun Checks geprüft. Fast alle bekamen ein B, aus Gründen, die der Inhaber nie gewählt hat.","2026-10-06","\u002Fblog\u002Fis-base44-safe\u002Fcard-800x500.png",{"path":947,"title":948,"description":949,"published":950,"category":700,"image":951,"draft":704},"\u002Fblog\u002Fmove-a-secret-to-an-edge-function","API-Schlüssel verstecken: ab in eine Supabase Edge Function","Einen API-Schlüssel verstecken heißt, ihn aus dem Browser zu nehmen. Eine Supabase Edge Function ist der kleinste Ort dafür, und zwei Schritte zählen mehr.","2026-10-05","\u002Fblog\u002Fmove-a-secret-to-an-edge-function\u002Fcard-800x500.png",{"path":953,"title":954,"description":955,"published":956,"category":700,"image":957,"draft":704},"\u002Fblog\u002Fenv-file-exposed-on-your-server","Ist deine .env-Datei öffentlich? Zwölf Pfade zum Prüfen","Ist deine .env-Datei auf deinem eigenen Webserver öffentlich? Zwölf Adressen sagen es dir, und ein Treffer heißt: alles darin ist längst öffentlich.","2026-10-04","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",{"path":959,"title":960,"description":961,"published":962,"category":700,"image":963,"draft":704},"\u002Fblog\u002Fis-v0-safe","v0-Sicherheit: alle 1.790 gescannten v0-Apps bekamen ein A","v0-Sicherheit, gemessen an 1.790 laufenden v0-Apps: Jede bekam ein A. Nur 17 nannten eine Datenbank, und genau das misst das A vor allem.","2026-10-03","\u002Fblog\u002Fis-v0-safe\u002Fcard-800x500.png",{"path":965,"title":966,"description":967,"published":968,"category":700,"image":969,"draft":704},"\u002Fblog\u002Fis-bolt-safe","Ist Bolt sicher? Was 1.123 echte Bolt-Apps zeigten","Ist Bolt sicher? Wir haben 1.123 laufende Bolt-Apps mit neun Checks geprüft. Das Hosting war sauber. Die Funde waren Schlüssel und offene Tabellen in den Apps.","2026-10-02","\u002Fblog\u002Fis-bolt-safe\u002Fcard-800x500.png",{"path":222,"title":971,"description":972,"published":973,"category":700,"image":974,"draft":704},"Ist Supabase down oder liegt es an deiner App? So erkennst du es","Ist Supabase down oder liegt es an deiner App? Ein pausiertes Projekt, eine volle Datenbank und ein eigener Fehler sehen gleich aus. Vier Prüfungen helfen.","2026-10-01","\u002Fblog\u002Fis-supabase-down-or-your-app\u002Fcard-800x500.png",{"path":976,"title":977,"description":978,"published":979,"category":700,"image":980,"draft":704},"\u002Fblog\u002Fdoes-supabase-encrypt-my-data","Verschlüsselt Supabase meine Daten? Ja. Wovor das schützt","Verschlüsselt Supabase Daten? Ja: AES-256 im Ruhezustand, TLS bei der Übertragung, SOC 2 und ISO 27001. Was jedes abdeckt und welches Leck keines stoppt.","2026-09-30","\u002Fblog\u002Fdoes-supabase-encrypt-my-data\u002Fcard-800x500.png",{"path":982,"title":983,"description":984,"published":985,"category":700,"image":986,"draft":704},"\u002Fblog\u002Fsupabase-free-plan-limits","Supabase Gratis-Tarif: die Limits und was an jedem passiert","Die Limits des Supabase-Gratis-Tarifs: 500 MB Datenbank, 5 GB Egress und keine Backups. Was an jeder Grenze passiert und was $25 für Pro ändern.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":988,"title":989,"description":990,"published":991,"category":807,"image":992,"draft":704},"\u002Fblog\u002Ftest-your-supabase-backup","Teste dein Supabase-Backup, bevor du es brauchst","So testest du dein Supabase-Backup: in ein Übungsprojekt einspielen, Zeilen zählen, anmelden und die Zeile suchen, die einer abgeschnittenen Datei fehlt.","2026-09-28","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":994,"title":995,"description":996,"published":997,"category":807,"image":998,"draft":704},"\u002Fblog\u002Fsupabase-backup-github-action","Kostenloses Supabase-Backup per GitHub Action, mit Haken","Eine Supabase-Backup-GitHub-Action kostet nichts und passt für viele Apps. Der Workflow, der richtige Connection String und das Egress pro Lauf.","2026-09-27","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcard-800x500.png",{"path":1000,"title":1001,"description":1002,"published":1003,"category":807,"image":1004,"draft":704},"\u002Fblog\u002Fdownload-your-supabase-backup","Warum du dein Supabase-Backup nicht herunterladen kannst","Dein Supabase-Backup kannst du auf aktuellen Projekten nicht herunterladen, weil die Tageskopie physisch ist. Wie du es prüfst und selbst eine Kopie hältst.","2026-09-26","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":1006,"title":1007,"description":1008,"published":1003,"category":700,"image":1009,"draft":704},"\u002Fblog\u002Fsupabase-permission-denied-for-table","Supabase \"permission denied for table\": der fehlende Grant","Ab 30. Oktober antwortet eine neue Supabase-Tabelle mit \"permission denied for table\", bis du Zugriff erteilst. Der Grant aus der E-Mail ist die halbe Lösung.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fcard-800x500.png",{"path":1011,"title":1012,"description":1013,"published":1014,"category":700,"image":1015,"draft":704},"\u002Fblog\u002Fopen-api-endpoint-exposed","Ist ein offener API-Endpunkt ein Sicherheitsproblem? Sieh ins JSON","Dein Scan hat einen offenen API-Endpunkt gemeldet. Ob das zählt, hängt davon ab, was zurückkam, und die meisten hier gehörten der Plattform.","2026-09-25","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",{"path":1017,"title":1018,"description":1019,"published":1020,"category":700,"image":1021,"draft":704},"\u002Fblog\u002Flovable-security-scan","Lovable Security Scan: das Eine, was er nicht beweist","Lovable Security Scan: was Quick Scan und Deep Scan prüfen, wann welcher läuft, und das Eine, was kein Scan von innen beweisen kann.","2026-09-24","\u002Fblog\u002Flovable-security-scan\u002Fcard-800x500.png",{"path":1023,"title":1024,"description":1025,"published":1026,"category":807,"image":1027,"draft":704},"\u002Fblog\u002Fsupabase-backup-auth-users","Warum in deinem Supabase-Dump keine Nutzer stehen","Führe supabase db dump allein aus und du bekommst die Form deiner Datenbank und keine einzige Zeile, und das auth-Schema mit deinen Nutzern fehlt ganz.","2026-09-23","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":1029,"title":1030,"description":1031,"published":1032,"category":700,"image":1033,"draft":704},"\u002Fblog\u002Fdomain-and-certificate-expiry","Domain abgelaufen, Website offline: was jetzt passiert","Deine Domain ist abgelaufen und deine Website ist offline. Welche Frist jetzt läuft, warum das Zertifikat das kleinere Problem ist, und wie du beides prüfst.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":1035,"title":1036,"description":1037,"published":1038,"category":700,"image":1039,"draft":704},"\u002Fblog\u002Fis-lovable-safe","Ist Lovable sicher? Was 18.554 echte Lovable-Apps zeigten","Ist Lovable sicher? Wir haben 18.554 laufende Lovable-Apps mit neun Checks geprüft. Die Plattform war die sauberste von fünf. Die Funde saßen in den Apps.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":1041,"title":1042,"description":1043,"published":1044,"category":700,"image":1045,"draft":704},"\u002Fblog\u002Fvibe-coded-app-security-checklist","Die Sicherheits-Checkliste für Vibe-Coding, in neun Prüfungen","Eine Sicherheits-Checkliste für Vibe-Coding mit neun Punkten, die jeder von außen an deiner Live-App nachprüfen kann, jeder mit einem Test in einer Zeile.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":1047,"title":1048,"description":1049,"published":1050,"category":700,"image":1051,"draft":704},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Ein geheimer Stripe-Schlüssel im Frontend kann Geld bewegen","Ein geheimer Stripe-Schlüssel im Frontend kann erstatten, abbuchen und jeden Kundendatensatz lesen, den du hast. Dein pk_live_-Schlüssel gehört dorthin.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":1053,"title":1054,"description":1055,"published":1056,"category":700,"image":1057,"draft":704},"\u002Fblog\u002Fvite-and-next-public-env-vars","Vite-Env-Variablen offengelegt: der Präfix heißt veröffentlichen","Vite-Env-Variablen offengelegt: Deine App hat getan, was der Präfix verlangt. VITE_ und NEXT_PUBLIC_ heißen veröffentlichen, und die KI kannte den Preis nie.","2026-09-18","\u002Fblog\u002Fvite-and-next-public-env-vars\u002Fcard-800x500.png",{"path":1059,"title":1060,"description":1061,"published":1062,"category":700,"image":1063,"draft":704},"\u002Fblog\u002Fbase44-source-maps","Base44-Sicherheit: was ein Scan meldet und was du ändern kannst","Base44-Sicherheit auf 5.438 gescannten Apps: Drei Befunde auf fast jeder gehören der Plattform, die Source Map ist das Base44-Badge, und deine Liste ist kurz.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":1065,"title":1066,"description":1067,"published":1068,"category":700,"image":1069,"draft":704},"\u002Fblog\u002Fis-cursor-ai-safe","Ist Cursor AI sicher? Editor, Code und die App, die du veröffentlichst","Ist Cursor AI sicher? Drei Fragen in einer Suche: was Cursor behält, was sein Code falsch macht und ob deine veröffentlichte App offen steht.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":1071,"title":1072,"description":1073,"published":1074,"category":700,"image":1075,"draft":704},"\u002Fblog\u002Fis-replit-safe","Ist Replit sicher? Was wir in 3.042 Replit-Apps gefunden haben","Ist Replit sicher? Wir haben 3.042 laufende Replit-Apps mit neun externen Checks geprüft. Die Funde saßen in der veröffentlichten App, nicht im Hosting.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":1077,"title":1078,"description":1079,"published":1080,"category":807,"image":1081,"draft":704},"\u002Fblog\u002Fsupabase-storage-backup","Supabase Storage Backup: deine Datenbankkopie hat keine Dateien","Ein Supabase Storage Backup ist eine eigene Aufgabe. Datenbank-Backups enthalten die Liste deiner Dateien und keine davon, also bleibt jeder Upload kaputt.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":1083,"title":1084,"description":1085,"published":1086,"category":807,"image":1087,"draft":704},"\u002Fblog\u002Fsupabase-point-in-time-recovery","Supabase Point-in-Time Recovery: Kosten und Grenzen","Supabase Point-in-Time Recovery spult deine Datenbank auf jede Sekunde der letzten Woche zurück. $100 im Monat zusätzlich zu Pro, und nur die Datenbank.","2026-09-13","\u002Fblog\u002Fsupabase-point-in-time-recovery\u002Fcard-800x500.png",{"path":1089,"title":1090,"description":1091,"published":1092,"category":807,"image":1093,"draft":704},"\u002Fblog\u002Fsupabase-project-paused-recover","Supabase-Projekt pausiert? Deine Daten sind noch da","Supabase hat dein Projekt nach einer Woche ohne Aktivität pausiert. Gelöscht ist nichts, Wiederherstellen steht neben dem Namen, und du hast ein Jahr.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":1095,"title":1096,"description":1097,"published":1098,"category":700,"image":1099,"draft":704},"\u002Fblog\u002Fsafest-ai-app-builder","Welcher KI-App-Builder ist am sichersten? 30.998 Apps im Test","Welcher KI-App-Builder ist am sichersten? Wir haben 30.998 aktive Apps von Lovable, Base44, Replit, v0 und Bolt gescannt. Der Builder entscheidet das nicht.","2026-09-11","\u002Fblog\u002Fsafest-ai-app-builder\u002Fcard-800x500.png",{"path":1101,"title":1102,"description":1103,"published":1104,"category":700,"image":1105,"draft":704},"\u002Fblog\u002Fenable-rls-on-every-supabase-table","Row Level Security für jede Supabase-Tabelle aktivieren und prüfen","Row Level Security in Supabase ohne Policy sperrt eine Tabelle komplett. Eine Policy ohne den Schalter bringt gar nichts. Hier ist das SQL, und der Test.","2026-09-10","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",{"path":1107,"title":1108,"description":1109,"published":1110,"category":700,"image":1111,"draft":704},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","Supabase \"RLS disabled in public\": was die Warnung übersieht","Supabase meldet \"RLS disabled in public\" als Fehler. Zur Lese-Policy, die deine Tabelle genauso offen lässt, sagt der Advisor gar nichts.","2026-09-09","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",{"path":1113,"title":1114,"description":1115,"published":1116,"category":700,"image":1117,"draft":704},"\u002Fblog\u002Frotate-supabase-service-role-key","Geleakten Supabase-service_role-Schlüssel richtig tauschen","Supabase sagt: erst das Leck schließen. Andere Anleitungen: sofort tauschen. Was richtig ist, hängt davon ab, wohin dein service_role-Schlüssel gelangt ist.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":1119,"title":1120,"description":1121,"published":1122,"category":700,"image":1123,"draft":704},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Vibe-Coding-Security-Scanner im Vergleich, unserer eingeschlossen","Der beste Vibe-Coding-Security-Scanner hängt an drei Fragen, die keine Funktionsliste beantwortet. Acht Tools im Vergleich, mit Preisen und unseren Lücken.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":1125,"title":1126,"description":1127,"published":1128,"category":700,"image":1129,"draft":704},"\u002Fblog\u002Fsupabase-security-checker","Supabase Security Checker: die fünf Prüfungen selbst machen","Ein Supabase Security Checker liest deine veröffentlichte App statt deiner Projekteinstellungen. Hier sind die fünf Prüfungen und wie du jede selbst ausführst.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":1131,"title":1132,"description":1133,"published":1134,"category":700,"image":1135,"draft":704},"\u002Fblog\u002Fvibe-coding-security-scanner","Vibe-Coding-Security-Scanner: was ein URL-Scan übersieht","Ein Vibe-Coding-Security-Scanner liest deine laufende App von außen. Was das abdeckt, die vier Dinge, die er nicht sehen kann, und wie du das Ergebnis liest.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":1137,"title":1138,"description":1139,"published":1140,"category":700,"image":1141,"draft":704},"\u002Fblog\u002Fmissing-security-headers","Fehlende Sicherheitsheader: wann sie wirklich zählen","Fehlende Sicherheitsheader ist unser häufigster Befund. Wogegen sie schützen, und wann sie die unwichtigste Zeile in deinem Bericht sind.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":1143,"title":1144,"description":1145,"published":1146,"category":700,"image":1147,"draft":704},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","Dein OpenAI-API-Schlüssel liegt im Frontend. Tausch ihn aus.","Ein OpenAI-API-Schlüssel im Frontend lässt sich an keine Domain binden. Tausch ihn heute, leg den Aufruf hinter deinen Server und begrenze das Budget.","2026-09-03","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":1149,"title":1150,"description":1151,"published":1152,"category":700,"image":1153,"draft":704},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","API-Schlüssel im Frontend: was 30.998 Apps wirklich ausliefern","Ein API-Schlüssel im Frontend ist meistens ein Google-Maps-Schlüssel. Wir haben 30.998 aktive Vibe-Coding-Apps gescannt und gezählt, was wirklich austritt.","2026-09-02","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcard-800x500.png",{"path":1155,"title":1156,"description":1157,"published":1158,"category":807,"image":1159,"draft":704},"\u002Fblog\u002Fsupabase-backup-tools-compared","Supabase-Backup-Tools im Vergleich, unseres eingeschlossen","Vier Arten von Supabase-Backup-Tool, was jedes wirklich kopiert und wann eine kostenlose GitHub Action jeden Anbieter schlägt, uns eingeschlossen.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":1161,"title":1162,"description":1163,"published":1164,"category":700,"image":1165,"draft":704},"\u002Fblog\u002Freplit-secrets-explained","Secrets in Replit nutzen, und was trotzdem veröffentlicht wird","Secrets in Replit nutzen: anlegen, auslesen und die zwei Gründe beheben, warum undefined zurückkommt. Dazu die Schlüssel, die das Werkzeug nicht schützt.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":1167,"title":1168,"description":1169,"published":1170,"category":807,"image":1171,"draft":704},"\u002Fblog\u002Fback-up-supabase-free-tier","Supabase Gratis-Tarif: Backup ohne Terminal selbst machen","Im Supabase Gratis-Tarif gibt es keine Backups, die Kopie musst du selbst machen. Wie das im Dashboard geht und was der CSV-Weg auslässt.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":1173,"title":1174,"description":1175,"published":1176,"category":700,"image":1177,"draft":704},"\u002Fblog\u002Fis-supabase-secure","Ist Supabase sicher? Ja. Dein Projekt ist eine eigene Frage","Ist Supabase sicher? Die Plattform ist auditiert, verschlüsselt und pentestet. Supabase schreibt selbst auf, wo das aufhört und deine Einstellungen anfangen.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":1179,"title":1180,"description":1181,"published":1182,"category":700,"image":1183,"draft":704},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Wo du deine Supabase API-Keys findest: anon, service_role, URL","Projekt-URL, anon-Schlüssel und service_role-Schlüssel liegen auf einer Seite im Dashboard. Wo sie ist, und welcher der vier Werte in deine App gehört.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":1185,"title":1186,"description":1187,"published":1188,"category":700,"image":1189,"draft":704},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","New row violates row-level security policy in Supabase: was jetzt?","\"New row violates row-level security policy\" heißt, Supabase hat einen Schreibvorgang abgelehnt. Die schnelle Lösung öffnet die Tabelle wieder für alle.","2026-08-27","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcard-800x500.png",{"path":1191,"title":1192,"description":1193,"published":1194,"category":700,"image":1195,"draft":704},"\u002Fblog\u002Fcors-wildcard-security-risk","Ist eine CORS-Wildcard ein Sicherheitsrisiko? Meist nicht.","Ist eine CORS-Wildcard ein Sicherheitsrisiko? Meist ist sie die Voreinstellung deines Builders und gibt nichts preis, was dein Server nicht ohnehin herausgab.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":1197,"title":1198,"description":1199,"published":1200,"category":807,"image":1201,"draft":704},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","Supabase Branching ist kein Backup. Es geht nur vorwärts.","Warum Supabase Branching kein Backup ist: Ein Branch startet ohne deine Daten, und ein Merge bringt nur das Schema. Wofür es gut ist und was stattdessen hilft.","2026-08-25","\u002Fblog\u002Fsupabase-branching-is-not-a-backup\u002Fcard-800x500.png",{"path":1203,"title":1204,"description":1205,"published":1206,"category":807,"image":1207,"draft":704},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Supabase-Backup wiederherstellen, und was danach kaputt ist","Wie du ein Supabase-Backup aus dem Dashboard oder aus einer Dump-Datei wiederherstellst, was ersetzt wird und warum die App danach kaputt sein kann.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":1209,"title":1210,"description":1211,"published":1212,"category":700,"image":1213,"draft":704},"\u002Fblog\u002Fsupabase-storage-bucket-public","Dein Supabase-Storage-Bucket ist öffentlich. Ist das ein Problem?","Ein öffentlicher Supabase-Storage-Bucket heißt: Wer die URL einer Datei hat, kann sie öffnen. Er heißt nicht, dass jemand den Inhalt auflisten darf.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":1215,"title":1216,"description":1217,"published":1218,"category":700,"image":1219,"draft":704},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","Ist ein Google-API-Schlüssel im Frontend ein Problem?","Ein Google-API-Schlüssel im Frontend ist der Fund unseres Scanners Nummer eins, und meistens unbedenklich. Eine kostenlose Einstellung entscheidet darüber.","2026-08-22","\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":1221,"title":1222,"description":1223,"published":1224,"category":807,"image":1225,"draft":704},"\u002Fblog\u002Fai-agent-deleted-my-database","Ein KI-Agent hat meine Supabase-Daten gelöscht. Was hole ich zurück?","Ein KI-Agent hat Daten aus deiner Datenbank gelöscht. Was du zurückholst, stand schon vorher fest, und die nächsten Minuten entscheiden über den Rest.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":1227,"title":1228,"description":1229,"published":1230,"category":700,"image":1231,"draft":704},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","Kann jeder deine Supabase-Datenbank lesen? 3.680 Apps im Test","Kann jeder deine Supabase-Datenbank ohne Login lesen? Wir haben 30.998 aktive Apps aus KI-Buildern gescannt und gemessen, wie oft die Antwort ja lautet.","2026-08-18","\u002Fblog\u002Fcan-anyone-read-your-supabase-database\u002Fcard-800x500.png",{"path":1233,"title":1234,"description":1235,"published":1230,"category":700,"image":1236,"draft":704},"\u002Fblog\u002Fsource-maps-exposed-in-production","Source-Maps öffentlich: deine App veröffentlicht ihren Quellcode","Eine öffentliche Source-Map lässt jeden den Originalcode deiner App lesen, Kommentare inklusive. Der 30-Sekunden-Check, und was wirklich zählt.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":1238,"title":1239,"description":1240,"published":1241,"category":700,"image":1242,"draft":704},"\u002Fblog\u002Fsupabase-new-api-keys","Supabase publishable key: ist er derselbe wie der anon key?","Supabase hat anon und service_role durch öffentliche und geheime Schlüssel ersetzt. Welcher gehört in deine App, und welcher nie?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":1244,"title":1245,"description":1246,"published":1247,"category":807,"image":1248,"draft":704},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","Sichert Supabase meine Datenbank? Das hängt von deinem Tarif ab.","Sichert Supabase deine Datenbank? Auf bezahlten Tarifen täglich, im Gratis-Tarif gar nicht. So findest du heraus, was du hast und was es nicht abdeckt.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":1250,"title":1251,"description":1252,"published":1253,"category":700,"image":1254,"draft":704},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","Supabase Row Level Security ist an. Die Tabelle ist trotzdem offen.","Supabase Row Level Security anzuschalten schützt keine Tabelle. Erst deine Policies tun das, und die, die deine App repariert hat, lässt oft alle herein.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":1256,"title":1257,"description":1258,"published":1253,"category":807,"image":1259,"draft":704},"\u002Fblog\u002Fversion-history-is-not-a-backup","Der Versionsverlauf ist kein Backup. Er holt keine Tabelle zurück.","Lovable und Bolt führen einen Versionsverlauf für deinen Code. Deine Datenbank ist ein eigener Dienst, und ein Rücksprung holt deine Daten nicht zurück.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":1261,"title":1262,"description":1263,"published":1264,"category":807,"image":1265,"draft":704},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","Drei Wege, eine Supabase-Datenbank zu sichern, und was fehlt","Das Dashboard, pg_dump und ein verwalteter Dienst. Was jeder Weg wirklich sichert, was er stillschweigend auslässt und welcher den Kontoverlust übersteht.","2026-08-09","\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database\u002Fcard-800x500.png",{"path":89,"title":1267,"description":1268,"published":1264,"category":700,"image":1269,"draft":704},"Welche API-Schlüssel im Frontend sicher sind, und welche nicht","Dein Supabase-anon-Schlüssel darf öffentlich sein. Der service_role-Schlüssel nicht. Er ignoriert jede Regel, die du setzt. So erkennst du den Unterschied.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1794213638762]