{"id":35,"date":"2010-02-23T10:16:09","date_gmt":"2010-02-23T09:16:09","guid":{"rendered":"https:\/\/alistapart.com\/it\/article\/il-problema-delle-password\/"},"modified":"2010-02-23T10:16:09","modified_gmt":"2010-02-23T09:16:09","slug":"il-problema-delle-password","status":"publish","type":"article","link":"https:\/\/alistapart.com\/it\/article\/il-problema-delle-password\/","title":{"rendered":"Il problema delle password"},"content":{"rendered":"<div class=\"paragrafo\">\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2010\/02\/password.jpg\" border=\"0\" alt=\"password\" width=\"167\" height=\"155\" style=\"float: left;\" \/>La recente <a href=\"http:\/\/www.useit.com\/alertbox\/passwords.html\">rubrica<\/a> del ricercatore esperto di usabilit\u00e0 Jakob Nielsen promuove un cambio fondamentale nella progettazione del campo password nel web. Egli ritiene che sia giunto il momento di mostrare le password in chiaro mentre l&#8217;utente le scrive, abbandonando l&#8217;approccio tradizionale consistente nel mostrare una serie di asterischi o pallini al posto della password stessa.<\/p>\n<p>La controversa proposta di Nielsen dimostra il principio secondo il quale la maggior parte delle decisioni progettuali sul web richiedono dei compromessi. Gli obiettivi degli utenti e gli obiettivi di business non si intersecano sempre. Questioni di sicurezza, usabilit\u00e0 ed estetica competono spesso tra loro. Dobbiamo darci delle priorit\u00e0 e bilanciare questi interessi per raggiungere i migliori risultati in qualunque situazione.<\/p>\n<p>Le problematiche di sicurezza sono pi\u00f9 difficili da gestire perch\u00e9 sono una seccatura. Tutto ci\u00f2 che vorremmo \u00e8 far s\u00ec che le persone raggiungano il fantastico tool che abbiamo sviluppato: invece dobbiamo costruire barriere tra l&#8217;utente e l&#8217;applicazione. Gli utenti devono dar prova della loro identit\u00e0. Non possiamo accettare nessun dato da essi, a meno che questi non siano stati scrupolosamente puliti.<\/p>\n<p>Sfortunatamente questa \u00e8 la realt\u00e0. Una buona parte del traffico web \u00e8 davvero maligno e i dati sensibili vengono rubati. Tipicamente, per accedere ad un&#8217;applicazione, chiediamo all&#8217;utente uno username (spesso un indirizzo email) ed una password ad esso collegata. Lo username identifica la persona, mentre la password prova che la persona che sta inserendo lo username \u00e8 proprio quella persona che ha creato l&#8217;account. Questa \u00e8 la teoria, basata su due assunzioni:<\/p>\n<ol>\n<li>una password non sar\u00e0 mai visibile al di fuori della testa della persona che l&#8217;ha creata,<\/li>\n<li>sia lo username sia la password possono essere richiamate dalla memoria al bisogno.<\/li>\n<\/ol>\n<p>Questo approccio mette un carico cognitivo significativo sulle persone che usano i siti web che richiedono l&#8217;autenticazione. In generale, ce la caviamo molto bene, ma \u00e8 facile vedere le debolezze di questo sistema. Le password facili da ricordare sono anche facili da indovinare. Quando le persone sono costrette a scegliere password forti, molto probabilmente le scriveranno o se le dimenticheranno. La risposta tipica a questo problema \u00e8 un meccaniscmo di reset, che naturalmente mina la solidit\u00e0 dell&#8217;intero sistema. Non importa quando la mia password sia criptata con il pi\u00f9 forte codice conosciuto all&#8217;uomo: pu\u00f2 semplicemente essere resettata da chiunque sappia quale scuola superiore io abbia frequentato.<\/p>\n<p>Questa \u00e8 una delle ragioni per cui Nielsen suggerisce di abbandonare il password masking: le persone si sentono frustrate e spesso resettano una password che non hanno effettivamente dimenticato, ma semplicemente sbagliato a digitare. Dare un feedback chiaro, senza lettere oscurate, ridurrebbe gli errori, aumentando la user experience e diminuendo il bisogno di alternative insicure.<\/p>\n<p>Tuttavia, apportare un cambiamento cos\u00ec radicale ad una fondamentale interazione con l&#8217;utente potrebbe presentare dei seri problemi. Considerate una situazione in cui una password debba essere inserita di fronte ad un folto gruppo di persone, ad esempio mentre si sta usando un proiettore durante una conferenza. E molti anni di esperienza web hanno creato delle aspettative su come dovrebbero funzionare gli elementi di una form. Le persone hanno capito che il password masking \u00e8 stato inventato per la loro sicurezza. Non riuscire a soddisfare queste aspettative pu\u00f2 minare la fiducia e noi non possiamo permetterci di perdere la fiducia degli utenti.<\/p>\n<p>C&#8217;\u00e8 una via di mezzo, un modo per fornire un feedback e ridurre gli errori nelle password che non sacrifichi la user experience? Almeno due schemi di progettazione affrontano questa questione nelle applicazioni offline e, con un po&#8217; di JavaScript, possiamo portarli sul web.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Ora lo vedi, ora non lo vedi<\/h2>\n<p>La soluzione pi\u00f9 semplice \u00e8 quella di mascherare la password di default e contemporaneamente dare la possibilit\u00e0 agli utenti di cambiare la modalit\u00e0 del campo a testo in chiaro. Perfino Nielsen incidentalmente menziona questa opzione. Questo approccio permette ad una persona di avere la conferma che la password sia stata inserita correttamente, ma pone anche il controllo fermamente nelle mani dell&#8217;utente. Questo meccanismo di cambio modalit\u00e0 si incontra spesso nel pannello preference del WiFi, ma \u00e8 raramente implementata altrove. (Nota: almeno un blog <a href=\"http:\/\/adactio.com\/journal\/1618\/\">ha propugnato una simile tecnica<\/a> mentre stavo scrivendo questo articolo.)<\/p>\n<p>Dovrebbe essere semplice scrivere un controllo che cambi da password a text l&#8217;attributo type di un elemento di input HTML. Sfortunatamente per\u00f2 non lo \u00e8. Internet Explorer non permette a JavaScript l&#8217;impostazione di questo particolare attributo, quindi dobbiamo essere un po&#8217; pi\u00f9 creativi. Le due funzioni seguenti dovrebbero fare al caso nostro:<\/p>\n<p>(Le righe che vanno a capo sono segnate con \u00bb ,<em>ndr.<\/em>)<\/p>\n<pre><code>window.onload = function() {<br \/>  if(document.getElementsByTagName) {<br \/>    var inputs = document.getElementsByTagName('input');<br \/>    for(var i in inputs) {<br \/>      var input = inputs[i];<br \/>      if(input.type == 'password') {<br \/>        toggle_control = document.createElement('label');<br \/>        toggle_control.innerHTML = \"&lt;input type=\\\"checkbox\\ \u00bb<br \/>        \" \"+ \"onclick=\\\"toggle_password('\"+ input.id+\"',this \u00bb<br \/>        .checked) \\\" \/&gt;\"+\" Show password\";<br \/>        input.parentNode.insertBefore(toggle_control, input \u00bb<br \/><br \/>        .nextSibling);<br \/>      }<br \/>    }<br \/>  }<br \/>}<br \/><br \/>function toggle_password(element_id, show_text) {<br \/>  if(document.getElementById) {<br \/>    var password_input = document.getElementById(element_id);<br \/>    var new_input      = document.createElement('input');<br \/>    with(new_input) {<br \/>      id        = password_input.id;<br \/>      name      = password_input.name;<br \/>      value     = password_input.value;<br \/>      size      = password_input.size;<br \/>      className = password_input.className;<br \/>      type      = show_text ? 'text' : 'password';<br \/>    }<br \/>    password_input.parentNode.replaceChild(new_input, \u00bb<br \/>    password_input);<br \/>  }<br \/>}<\/code><\/pre>\n<p>La prima funziona fa una scansione del documento per cercare tutti gli elementi input e mette da parte quelli con type password. Si tenga presente che questo codice ha il solo scopo di dimostrare il concetto e che il processo potrebbe essere migliorato usando un framework JavaScript come <a href=\"http:\/\/www.prototypejs.org\/\" title=\"link al sito di \">Prototype<\/a>.<\/p>\n<p>Dopo ogni input, la funzione inserisce un checkbox con un label che permette di cambiare il campo da testo oscurato e testo in chiaro. La seconda funzione controlla il comportamento stesso del cambio: quando l&#8217;utente clicca sul controllo per il cambio, la funzione crea un nuovo elemento input e lo scambia con quello esistente, passando il valore e le altre propriet\u00e0 da un elemento input all&#8217;altro.<\/p>\n<p>Un approccio alternativo \u00e8 quello di creare il testo di input una sola volta e di scambiare le propriet\u00e0 di display per mostrare o nascondere il campo appropriato. Uno svantaggio di questo metodo, tuttavia \u00e8 che l&#8217;id dell&#8217;elemento deve essere unico. Dal momento che il testo di input parallelo avr\u00e0 il suo proprio id, non erediter\u00e0 alcuna regola CSS che faceva riferimento all&#8217;elemento originale mediante l&#8217;ID.<\/p>\n<p>Guardate <a href=\"https:\/\/alistapart.github.io\/code-samples\/the-problem-with-passwords\/example-one-password-masking-toggle.html\" title=\"link all'esempio uno su A List Apart\">l&#8217;esempio uno<\/a> per vedere questa tecnica in azione. Questa soluzione \u00e8 facile da implementare e segue il principio del <a href=\"http:\/\/www.alistapart.com\/articles\/understandingprogressiveenhancement\" title=\"link all'articolo in inglese su A List Apart su\">progressive enhancement<\/a>: in mancanza di JavaScript, i campi password manterrano il loro solito comportamento. Il controllo per lo scambio d\u00e0 il potere all&#8217;utente di poter scegliere tra il mostrare una password o il nasconderla in circostanze particolari. Il principale svantaggio \u00e8 che potrebbe ancora minare il concetto di un utente del campo password come &#8220;black box&#8221; (scatola nera). Siamo cos\u00ec totalmente abituati a pensare alle nostre password come ad un segreto che il solo offrire l&#8217;opzione di mostrarla in chiaro potrebbe sconvolgerci.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Seconda alternativa<\/h2>\n<p>Gli errori di battitura sono particolarmente comuni sui dispositivi touchscreen come gli iPhone, dove le dita non possono sentire al tatto i confini di un tasto. Prevedendo che l&#8217;inserimento di password senza un feedback visivo potrebbe causare dei problemi, Apple ha adottato un approccio interessante: l&#8217;ultima lettera inserita nel campo rimane visibile per un paio di secondi prima di trasformarsi in un pallino. Ci\u00f2 crea la possibilit\u00e0 di trovare gli errori senza mostrare l&#8217;intera password tutta insieme.<\/p>\n<p>Possiamo riprodurre questo oscuramento progressivo della password con HTML e JavaScript, sebbene ci vorr\u00e0 un po&#8217; pi\u00f9 di codice che per il precedente esempio. Considerate quanto segue:<\/p>\n<pre><code>window.onload = function() {<br \/>  if(document.getElementsByTagName) {<br \/>    var inputs = document.getElementsByTagName('input');<br \/>    var password_inputs = Array();<br \/>    for(var i in inputs) {<br \/>      if(inputs[i].type == 'password') {<br \/>        password_inputs.push(inputs[i]);<br \/>      }<br \/>    }<br \/>    for(var i in password_inputs) {<br \/>      var input = inputs[i];<br \/>    <br \/>      var masking_element = document.createElement('input');<br \/>      with(masking_element) {<br \/>        style.position = 'absolute';<br \/>        id             = input.name + '_mask';<br \/>        type           = 'text';<br \/>        size           = input.size;<br \/>        className      = input.className;<br \/>      }<br \/>      masking_element.onfocus = function(){this.nextSibling \u00bb<br \/>      .focus()};<br \/>      input.parentNode.insertBefore(masking_element, input);<br \/>      <br \/>      input.onchange = function() {<br \/>        <br \/>        if(this.timer){<br \/>          clearTimeout(this.timer);<br \/>        }<br \/>        <br \/>        var mask_character = \"\\u2022\";<br \/>        var last_character = this.value.charAt(this \u00bb<br \/>        .value.length-1);<br \/>        <br \/>        var masked_text    = this.previousSibling.value;<br \/>        var password_text  = this.value;<br \/>        <br \/>        if(masked_text.length &lt; password_text.length) {<br \/>          this.previousSibling.value = password_text.substr(0,<br \/>            password_text.length-1).replace(\/.\/g,<br \/>            mask_character)+last_character;<br \/>        } else {<br \/>          this.previousSibling.value = password_text \u00bb<br \/><br \/>          .replace(\/.\/g,mask_character);<br \/>        }<br \/>        this.timer = setTimeout(\"with(document.getElement \u00bb<br \/>        ById('\"+masking_element.id+\"')){value=value \u00bb<br \/>        .replace(\/.\/g,'\"+mask_character+\"')}\",2000);<br \/>      <br \/>      }<br \/>      input.onkeyup = input.onchange;<br \/>      input.onchange();<br \/><br \/>    }<br \/>  }<br \/>}<\/code><\/pre>\n<p>Questa volta, abbiamo creato un secondo text input che si mette direttamente sopra ogni password input (gli avvertimenti sull&#8217;ereditariet\u00e0 dei CSS dell&#8217;esempio precedente si applicano a questo). Manipolando il suo valore al mutare del campo originale, possiamo controllare quello che l&#8217;utente vede. Analizziamo ogni step dello script.<\/p>\n<pre><code>window.onload = function() {<br \/>  if(document.getElementsByTagName) {<br \/>    var inputs = document.getElementsByTagName('input');<br \/>    var password_inputs = Array();<br \/>    for(var i in inputs) {<br \/>      if(inputs[i].type == 'password') {<br \/>        password_inputs.push(inputs[i]);<br \/>      }<br \/>    }<br \/>    for(var i in password_inputs) {<br \/>      var input = inputs[i];<br \/>      ...<br \/>    }<br \/>  }<br \/>}<\/code><\/pre>\n<p>Ancora una volta, il nostro primo task fa una scansione della pagina cercando i password input cos\u00ec che noi si possa poi modificare il loro comportamento. Tuttavia, c&#8217;\u00e8 una differenza sostanziale tra questa funzione e quella del primo esempio: in Internet Explorer, <code>document.getElementsByTagName()<\/code> non ritorna una semplice lista di elementi che vanno bene nel momento in cui lo script parte, ma ritorna un riferimento alla collezione di elementi che vanno bene. Se creiamo un nuovo elemento input mentre facciamo il loop sui risultati, aumenteremmo la dimensione di tale collezione ad ogni passo, ed il loop continuerebbe all&#8217;infinito. Questo fa bloccare istantaneamente Internet Explorer (e senza grazia!). Quindi, abbiamo bisogno di copiare i risultati iniziali della funzione in un array e fare un loop su questo.<\/p>\n<pre><code>var masking_element = document.createElement('input');<br \/>with(masking_element) {<br \/>  style.position = 'absolute';<br \/>  id             = input.name + '_mask';<br \/>  type           = 'text';<br \/>  size           = input.size;<br \/>  className      = input.className;<br \/>}<br \/>masking_element.onfocus = function(){this.nextSibling.focus()};<br \/>input.parentNode.insertBefore(masking_element, input);<\/code><\/pre>\n<p>Con il nuovo input inserito direttamente prima di quello esistente, mettere la sua <code>position<\/code> ad <code>absolute<\/code> dovrebbe piazzarlo direttamente sopra. Dovrebbe funzionare nella maggior parte dei layout, ma ci possono essere delle eccezioni dove dei CSS aggiuntivi sono richiesti per posizionarlo correttamente. Ovviamente, ora che stiamo comprendo l&#8217;input con un altro elemento, abbiamo anche bisogno di essere sicuri che cliccando sulla maschera si attivi l&#8217;input. l&#8217;aggiunta di un handler <code>onfocus<\/code> sistema questo aspetto. Dobbiamo mettere questo handler all&#8217;esterno della dichiarazione <code>with<\/code> affinch\u00e9 funzioni correttamente in Firefox 2.<\/p>\n<pre><code>input.onchange = function() {<br \/>  ...  <br \/>}<br \/>input.onkeyup = input.onchange;<\/code><\/pre>\n<p>Con il nuovo elemento al suo posto, costruiremo una funzione che mostri il testo della password progressivamente nascosto. Abbiamo bisogno che questo testo risponda ai cambiamenti nel contesto del campo password. Solitamente, questo implica che un utente sta scrivendo con una tastiera, ma potrebbe benissimo non essere cos\u00ec. Qualcuno potrebbe copiare il testo nel campo usando un menu contestuale, per esempio. Attaccare il nostro codice sia all&#8217;evento <code>change<\/code> sia all&#8217;evento <code>keyup<\/code> dovrebbe coprire tutte le situazioni.<\/p>\n<pre><code>var mask_character = \"\\u2022\";<br \/>var last_character = this.value.charAt(this.value.length-1);<\/code><\/pre>\n<p>Possiamo designare qualunque carattere ci piaccia per mascherare le password. Tradizionalmente, la maggior parte dei sistemi usa asterischi o pallini, cos\u00ec in questo esempio abbiamo definito l&#8217;entit\u00e0 Unicode 2022, ossia il carattere del punto elenco come carattere che nasconder\u00e0 la password. Sulla seconda linea, identifichiamo l&#8217;ultimo carattere dell&#8217;attuale valore della password, cos\u00ec da poterlo rendere in chiaro.<\/p>\n<pre><code>var masked_text    = this.previousSibling.value;<br \/>var password_text  = this.value;<br \/><br \/>if(masked_text.length &lt; password_text.length) {<br \/>  this.previousSibling.value = password_text.substr(0,<br \/>  password_text.length-1).replace(\/.\/g, \u00bb<br \/>  mask_character)+last_character;<br \/>} else {<br \/>  this.previousSibling.value = password_text.replace(\/.\/g,<br \/>                                 mask_character);<br \/>}<\/code><\/pre>\n<p>Adesso possiamo prendere il valore del campo password, rimpiazzare ogni carattere con un bullet (carattere punto elenco) tranne l&#8217;ultimo e mettere quel testo nel campo che stiamo usando come maschera. Comunque, possiamo farlo solo mentre una persona sta inserendo i caratteri procedendo in avanti. In altre parole, se l&#8217;utente schiaccia il tasto backspace (delete) non riveliamo un&#8217;altra volta il carattere precedente. Una volta nascosto, il carattere dovrebbe rimanere nascosto. Cos\u00ec, prima di fare la sostituzione del carattere, dobbiamo controllare per verificare che il valore della password non sia pi\u00f9 lungo del testo oscurato. La sostituzione stessa pu\u00f2 essere fatta usando una semplice espressione regolare. L&#8217;espressione <code>\/.\/<\/code> eguaglia ciascun carattere del campo password. Aggiungendo al lettera <code>g<\/code> alla fine, (<code>\/.\/g<\/code>) viene fatta una scansione dell&#8217;intera stringa di testo invece che fermarsi al primo che eguaglia.<\/p>\n<pre><code>this.timer = setTimeout(\"with(document.getElementById('\"+<br \/>  masking_element.id+\"')){value=value.replace(\/.\/g,'\"+<br \/>  mask_character+\"')}\",2000);<\/code><\/pre>\n<p>Dopo un ritardo di due secondi, vogliamo che l&#8217;intera password sia oscurata. Tuttavia, i nostri utenti probabilmente non si fermeranno per due secondi dopo aver inserito ogni singola lettera. Pertanto vogliamo che il comportamento auspicato abbia effetto solo quando il campo password non \u00e8 cambiato affatto per tale intervallo di tempo. Ogni volta che chiamiamo la funzione <code>setTimeout<\/code> in JavaScript, ci ritorna come risultato un ID che possiamo usare per referenziare quel particolare timer.<\/p>\n<pre><code>if(this.timer){<br \/>  clearTimeout(this.timer);<br \/>}<\/code><\/pre>\n<p>Memorizzando l&#8217;ID del timer in una variabile ed aggiungendo il codice di cui sopra all&#8217;inizio della nostra funzione, possiamo cancellare il countdown fintanto che osserviamo che il campo sta cambiando.<\/p>\n<pre><code>input.onchange();<\/code><\/pre>\n<p>L&#8217;ultimo step consiste nel far girare la funzione che abbiamo appena definito. Questo assicura che la maschera mostrer\u00e0 il testo corretto se il campo password era stato riempito in anticipo prima che la pagina si caricasse.<\/p>\n<p>Per vedere l&#8217;intero script in azione, guardate <a href=\"https:\/\/alistapart.github.io\/code-samples\/the-problem-with-passwords\/example-two-password-progressive-masking.html\">l&#8217;esempio due<\/a>. E&#8217; stato testato in Internet Explorer 6-8, Firefox, Safari e Chrome. Ribadisco che in assenza di JavaScript questa tecnica degrada bene: il campo password semplicemente funzioner\u00e0 in maniera normale.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Procedete con cautela<\/h2>\n<p>Quando si ha a che fare con un&#8217;area cos\u00ec importante dell&#8217;esperienza web, dobbiamo prestare molta attenzione perch\u00e9 abbiamo a che fare con aspettative molto radicate. Il metodo username\/password usato per mettere in sicurezza le applicazioni web non \u00e8 perfetto, ma ci sono poche buone alternative ed \u00e8 diventato un approccio standard. Possiamo affrontare meglio le preoccupazioni riguardanti l&#8217;usabilit\u00e0 dei campi password testando dei cambi incrementali per estendere il comportamento di default, senza compromettere le basi dell&#8217;esperienza e non perdere la fiducia degli utenti.<\/p>\n<\/div>\n<div id=\"approfondisci\">\n<p>Pubblicato in: <a href=\"argomenti?topic=Browser&amp;tid=4\">Browsers<\/a> e <a href=\"argomenti?topic=Scripting&amp;tid=19\">Scripting<\/a>.<\/p>\n<\/div>\n<div id=\"credits\">\n<ul>\n<li>Illustrazioni create da <a href=\"http:\/\/www.mondonascosto.com\/\">Carlo Brigatti<\/a><\/li>\n<\/ul>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>La recente rubrica del ricercatore esperto di usabilit\u00e0 Jakob Nielsen promuove un cambio fondamentale nella progettazione del campo password nel web. Egli ritiene che sia giunto il momento di mostrare le password in chiaro mentre l&#8217;utente le scrive, abbandonando l&#8217;approccio tradizionale consistente nel mostrare una serie di asterischi o pallini al posto della password stessa.<\/p>\n","protected":false},"author":818,"featured_media":7000567,"comment_status":"open","ping_status":"open","template":"","categories":[242,271,11,9],"tags":[],"coauthors":[284],"class_list":["post-35","article","type-article","status-publish","has-post-thumbnail","hentry","category-browser","category-javascript","category-numero-uno-23-febbraio-2010","category-usabilita"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/article\/35","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/article"}],"about":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/types\/article"}],"author":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/users\/818"}],"replies":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/comments?post=35"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/media\/7000567"}],"wp:attachment":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/media?parent=35"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/categories?post=35"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/tags?post=35"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/coauthors?post=35"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}