Specifiche delle chiavi API utente

Trovo che il valore predefinito di allowed_user_api_auth_redirects, ovvero “discourse://auth_redirect”, sia piuttosto restrittivo, soprattutto perché “discourse” non sembra essere uno schema URI valido.

Potreste spiegare la logica alla base di questa impostazione predefinita? Grazie.

Anch’io ho questo problema. Se avvio l’API da un’applicazione JS, automaticamente le intestazioni consentite sono: User-Api-Key, User-Api-Client-Id, anche se non ho bisogno di chiavi API utente. Voglio solo una semplice chiave API, ma non riesco a far funzionare nulla. Se provo a passare Api-Key nelle intestazioni, ricevo un errore CORS perché si aspetta User-Api-Key. Ma quando provo a usare User-Api-Key, ricevo errori 403. Sono bloccato. Pensavo che questo fosse l’uso base delle API. Non sto cercando di fare nulla di straordinario. Sto semplicemente cercando di creare un nuovo post nell’argomento.

2 Mi Piace

Questo è lo schema URI personalizzato utilizzato dall’app DiscourseHub per iOS e Android.

6 Mi Piace

Ho una domanda riguardo ai “token di lettura” e ai “token di scrittura”. Questo commento è del 2016, quindi è possibile che sia già stato modificato? O le impostazioni predefinite sono ancora solo “token di lettura”?

Contesto: sono uno degli sviluppatori dietro un sistema di social media distribuito. Abbiamo già dei connettori per sistemi non federati. L’idea è di scrivere anche un’estensione per Discourse. Ma dato che probabilmente la maggior parte dei sistemi non consentirà agli utenti di generare token che permettano la pubblicazione, proveremo un’altra strada. Abbiamo già un connettore per la posta. Utilizzeremo semplicemente la funzione di mailing list di Discourse e cercheremo di migliorare il contenuto restituito, pubblicando tramite SMTP.

Puoi scrivere token se richiedi l’ambito in anticipo

3 Mi Piace

Certo, è sempre possibile. Ma ho la sensazione che si tratti di un incubo per il supporto. Il nostro software ha alcune centinaia di installazioni con (in totale) oltre 10.000 utenti. Quando vedranno che esiste un addon che si connette a Discourse, molti vorranno sicuramente utilizzarlo. E dato che molto probabilmente non funzionerà immediatamente, questo genererà domande e lavoro di supporto da parte nostra. Inoltre, creerà lavoro per gli amministratori delle varie installazioni di Discourse. E molto probabilmente non tutti lo permetteranno, il che causerà frustrazione.

Quindi, forse all’inizio mi concentrerò sull’integrazione delle email della modalità mailing list. Oppure è possibile combinare queste due cose? Cioè: leggere i post tramite l’API, ma pubblicare tramite SMTP?

Ciao… non so come generare la public_key… devo usare un generatore RSA per ottenere la coppia di chiavi pubblica/privata?
Se è così, ho utilizzato alcuni generatori RSA online, ma ricevo questo errore:

OpenSSL::PKey::RSAError (Neither PUB key nor PRIV key: nested asn1 error) /var/www/discourse/app/controllers/user_api_keys_controller.rb:189:in `initialize'

Inoltre, vorrei chiedervi se questa soluzione è adatta al mio caso d’uso:
Ho un’applicazione e vorrei principalmente autenticare l’utente e ottenere il nome utente. Generare un flusso di API key è la soluzione più semplice per validare l’accesso dell’utente nella mia app? Se possibile, vorrei evitare SSO perché sembra più complicato.

Stessa situazione qui, anche se sto cercando di usare solo User-Api-Key (non Api-Key) per creare un post nel forum e ricevo un rifiuto CSRF dalla libreria actionpack.

A meno che il server Discourse non abbia disattivato il controllo CSRF, sembra difficile pubblicare da un’app desktop di terze parti. Non ho intenzione di emulare un browser.

@sam, qual è la tua opinione sull’uso di chiavi API utente con solo l’ambito read abilitato, passate come parametri URL nelle richieste GET?

Il caso d’uso è consentire integrazioni come l’iscrizione dei tuoi Segnalibri migliorati con promemoria su Google Calendar utilizzando le chiavi API utente.

5 Mi Piace

Che ne dite di creare un nuovo ambito specifico, con un terzo parametro per indicare ‘parametro GET consentito’? In questo modo, gli utenti non potranno abusarne per altri scopi (ad esempio, aggirare CORS e richiedere l’API di Discourse da un altro sito).

(da qui)

SCOPES = {
    read: [:get],
    write: [:get, :post, :patch, :put, :delete],
    message_bus: [[:post, 'message_bus']],
    push: nil,
    one_time_password: nil,
    notifications: [[:post, 'message_bus'], [:get, 'notifications#index'], [:put, 'notifications#mark_read']],
    session_info: [
      [:get, 'session#current'],
      [:get, 'users#topic_tracking_state'],
      [:get, 'list#unread'],
      [:get, 'list#new'],
      [:get, 'list#latest']
    ],
+   calendar: [ [:get, 'users#bookmarks_cal', true ] ],
  }

(A parte: perché stiamo usando array annidati qui…)

10 Mi Piace

Mi piace che la chiave API venga esplicitamente contrassegnata come “permessa in GET” a livello utente.

Nel complesso, l’opzione potrebbe essere aperta a qualsiasi richiesta GET. La regola che preferisco, quando si opera in questa modalità, è:

  1. La chiave API dell’utente è limitata al 100% a una singola azione di controller GET specifica
  2. La chiave API dell’utente è contrassegnata come permessa nei parametri di query GET.

Questo limita l’impatto di eventuali fughe di dati tramite un proxy, poiché la chiave non verrà mai riutilizzata.

Immagino che {get: 'list#new'}, {get: 'list#latest'} funzionerebbe altrettanto bene.

7 Mi Piace

Sono super interessato alle chiavi API utente di tipo ‘get param only’. La mia domanda è: avete intenzione di permettere agli utenti di generare queste chiavi tramite l’interfaccia grafica?

Probabilmente, forse dietro un’impostazione del sito o con un plugin. Abbiamo intenzione di uniformare un po’ le funzionalità in modo che anche le chiavi API di amministrazione supportino gli ambiti.

4 Mi Piace

Ciao… Sei in grado di risolvere questo problema? Ho lo stesso problema e non riesco a risolverlo. Ho provato a passare diversi tipi di chiavi, ma nulla ha funzionato. Qualsiasi aiuto sarebbe molto apprezzato.

Esistono librerie per questo? In caso contrario, un esempio di implementazione? Sto cercando di utilizzare PHP per identificare l’account Discourse di un utente in una sezione separata del sito web. Sembra un flusso OAuth modificato, ma sono un po’ confuso su come implementarlo.

In particolare, non sono sicuro di come gestire l’intera generazione delle chiavi pubblica/privata.

Esiste un modo per utilizzare semplicemente OAuth 2 con Discourse come provider OAuth?

2 Mi Piace

Sei riuscito a farlo usando la User-Api-Key? Sto ricevendo anch’io il messaggio ‘You are not permitted to view the requested resource’.

1 Mi Piace

Ho capito cosa ho fatto di sbagliato: il payload restituito non è la chiave API di UserAPI stessa, ma una stringa JSON cifrata, che deve essere decifrata con la chiave privata della coppia di chiavi pubblica/privata.

2 Mi Piace

AGGIORNAMENTO: Sono riuscito a far funzionare la maggior parte delle cose e fornirò una descrizione non appena avrò completato il tutto.


Come fa il client a ottenere la coppia di chiavi privata/pubblica e l’ID?

Potete fornire del codice per ottenere la chiave API dell’utente con un’app JavaScript? (Un’app JavaScript che cerca di permettere a un utente di effettuare chiamate API a un forum Discourse).

Sto ricevendo errori 403. Oppure un errore che dice: Spiacenti, non siamo in grado di emettere chiavi API per gli utenti; questa funzionalità potrebbe essere disabilitata dall'amministratore del sito (anche se nel mio sito è spuntata l’opzione: Consenti la generazione di chiavi API per gli utenti).

Penso che il problema possa essere legato a come generare la coppia di chiavi privata/pubblica (come si fa?) e poi a come gestire il reindirizzamento.

Qualsiasi codice è apprezzato.

Sono riuscito a farlo funzionare, dopo qualche tentativo ed errore.

Ecco i passaggi di base che seguo quando: ho un’app separata che ho codificato e voglio che gli utenti possano utilizzarla per effettuare chiamate API a un sito Discourse.

Per fare ciò, devo generare un token API per utente per effettuare chiamate per conto di ogni utente specifico (almeno in un ambiente Node.js/JavaScript).


Nota: per la parte JavaScript, ho trovato molto utile il codice fornito da @KengoTODA qui: discourse-api-key-generator/src/index.ts at main · KengoTODA/discourse-api-key-generator · GitHub


Ecco i passaggi che ho seguito:

Primo: Generare una coppia di chiavi pubblica e privata.

Questo è qualcosa che la tua app deve generare: una chiave pubblica e una chiave privata. Il gist di GitHub fornisce un metodo per farlo.

Secondo: Avere un URL di reindirizzamento.

Questo è l’URL a cui Discourse reindirizzerà, fornendo il token API finale nel payload. Se hai un’app desktop (cioè senza URL del browser), l’URL di reindirizzamento si baserà su un protocollo personalizzato che hai configurato e che apre l’app quando l’URL di reindirizzamento viene inserito nel browser.

Nota che l’URL di reindirizzamento deve essere inserito nella whitelist nelle impostazioni del sito del sito Discourse di destinazione.

Il sito Discourse deve anche probabilmente avere attiva l’impostazione del sito “Consenti chiavi API utente”. Consulta il post originale su questo argomento per le “Impostazioni del sito”.

Terzo: Inviare la chiamata della richiesta API all’URL di richiesta di Discourse.

La tua app invierà quindi una chiamata a un URL che segue questo formato:

https://[il tuo sito Discourse di destinazione .com]/user-api-key-new"

aggiungendo come parametri:

  • il nome della tua app
  • il tuo “client_id” (sono riuscito a usare hostname(), da const {hostname} = require('os') per un’app desktop, proprio come nel gist di GitHub citato sopra)
  • gli ambiti (questi sono gli ambiti che desideri che l’utente possa utilizzare tramite l’API, come “write”, “read”, ecc.)
  • la tua chiave pubblica (dal passaggio 1 sopra)
  • il tuo URL di reindirizzamento (dal passaggio 2 sopra)
  • nonce (questo è un valore che puoi scegliere: ad esempio, usare semplicemente ‘1’ sembra funzionare)

Quarto: L’utente autorizza la tua app sulla pagina del sito Discourse aperta dall’URL di richiesta

Quando invii con successo l’URL di richiesta, si apre una pagina sul sito Discourse che informa l’utente che la tua app vuole accedere al sito.

Su quella pagina, c’è un pulsante per l’utente per consentire questa operazione. Quando l’utente clicca su questo pulsante, il sito Discourse reindirizza all’URL di reindirizzamento che hai fornito e allega come parametro ?payload=[LA CHIAVE API]. LA CHIAVE API qui è la chiave che devi decodificare nella tua app.

Quinto: La tua app riceve il valore dell’URL di reindirizzamento (con il valore del payload) e decodi la CHIAVE API

Sei quasi arrivato. La tua app deve analizzare l’URL di reindirizzamento a cui è andato Discourse e ottenere la Chiave API contenuta nel payload.

Una volta ottenuta quella Chiave API, devi fare due cose:

  1. Ottenere la chiave effettiva, non la versione codificata nell’URL: se stai ottenendo un parametro da un URL, spesso è codificato nell’URL (aggiungendo % qui e là, ecc.). Devi pulirlo. In JavaScript, ho trovato che decodeURIComponent funziona per questo.
  2. Una volta ottenuta la CHIAVE API ripulita restituita da Discourse, devi decodificarla. Per fare ciò, puoi usare la decodifica JavaScript con le chiavi private. Fondamentalmente, usi la tua chiave privata (generata nel primo passaggio sopra) per decodificare la CHIAVE API ripulita. C’è qualche esempio JavaScript nel gist di GitHub che ho citato sopra: discourse-api-key-generator/src/index.ts at main · KengoTODA/discourse-api-key-generator · GitHub

Dopo aver eseguito il tuo codice di decodifica, hai il token stesso, che ora puoi usare per effettuare chiamate API autenticate per conto dell’utente.

Sesto: Usa il token (cioè la CHIAVE API finale, ripulita e decodificata) per effettuare chiamate API per conto dell’utente

Con quel token, sembra che non sia necessario inserire il nome utente nella chiamata API. Trovo che l’intestazione seguente sia sufficiente quando la includi nelle tue chiamate GET, POST, PUT, ecc.:

headers: {
"User-Api-Key": [il token]
}

E con questo, speriamo tu abbia un metodo di autenticazione per utente funzionante per interagire con Discourse.

7 Mi Piace

Quali sono le implicazioni di sicurezza dell’aggiunta di elementi a allowed_user_api_auth_redirects? Ho una persona che chiede di aggiungere una stringa per supportare l’integrazione NextCloud.

1 Mi Piace