MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Autenticati dopo aver selezionato il database

Sembra che ti manchino alcuni concetti qui, quindi sostanzialmente risponderò come una "guida" a cosa dovresti invece fare. Quindi "l'autenticazione" non è davvero qualcosa che fai "dopo" la connessione, ma piuttosto devi "cercare nel posto giusto" quando tenti effettivamente di autenticarti.

Possiamo iniziare essenzialmente seguendo il processo descritto in Enable Auth dalla documentazione di base, ma modificato in modo specifico perché desideri eseguire questo "test" con il tuo account utente e la tua directory locale.

Passaggi di revisione - Direttamente dalla documentazione

Quindi prima vorresti scegliere una directory di lavoro locale e creare un percorso per i file di archiviazione del database al di sotto di essa. Sui sistemi basati su *nix puoi fare qualcosa come:

mkdir -p scratch/data/db
cd scratch

Quindi vogliamo avviare un'istanza MongoDB separata senza altre opzioni. Assicurarsi che la porta non sia in conflitto con altre istanze in esecuzione:

mongod --port 37017 --dbpath data/db

In un nuovo terminale o finestra della riga di comando, puoi quindi connetterti alla shell:

mongo --port 37017

Vuoi sempre almeno un account con privilegi di amministratore per almeno "creare account" e modificarli in caso di problemi, quindi creane uno:

use admin
db.createUser(
  {
    user: "admin",
    pwd: "admin",
    roles: [{ role: "userAdminAnyDatabase", db: "admin" }]
  }
)

Ora esci dalla shell e chiudi il mongod esistente istanza in esecuzione nell'altro terminale o prompt dei comandi, quindi riavviarlo utilizzando --auth :

mongod --auth --port 37017 --dbpath data/db

Utente specifico:assicurati di seguire questi

Ora vuoi effettivamente creare un utente che sarà "utilizzato dalla tua applicazione". Quindi questi passaggi sono importanti per assicurarti di farlo bene.

Accedi a una shell usando il tuo "utente amministratore":

mongo -u admin -p admin --port 37017 --authenticationDatabase 'admin'

In alternativa puoi eseguire db.auth() metodo come mostrato nella domanda, ma come notato questo deve essere autorizzato su "admin" spazio dei nomi.

La prossima cosa che vuoi fare è creare un utente con accesso a "mydb" come spazio dei nomi con readWrite ruolo. Per i kick, consentiremo anche a questo utente di avere il readAnyDatabase consentendo loro di "elencare" tutti gli spazi dei nomi dei database, se non in grado di fare nient'altro con essi.

use admin
db.createUser(
  {
    "user": "myuser",
    "pwd": "password",
    "roles": [
      { "role": "readWrite", "db": "mydb" },
      "readAnyDatabase"
    ]
  }
)

Solo per ulteriore output, diamo un'occhiata agli utenti attualmente creati:

db.getUsers()
[
        {
                "_id" : "admin.admin",
                "user" : "admin",
                "db" : "admin",
                "roles" : [
                        {
                                "role" : "userAdminAnyDatabase",
                                "db" : "admin"
                        }
                ]
        },
        {
                "_id" : "admin.myuser",
                "user" : "myuser",
                "db" : "admin",
                "roles" : [
                        {
                                "role" : "readWrite",
                                "db" : "mydb"
                        },
                        {
                                "role" : "readAnyDatabase",
                                "db" : "admin"
                        }
                ]
        }
]

Guarda come si sono espansi nella denominazione, e in particolare i valori assegnati ai vari "db" chiavi su ciascun utente. Questo dovrebbe darti un'idea in più di come MongoDB lo cerca e perché.

Connessione Python

Alla fine vogliamo solo connetterci da Python. Quindi, supponendo che tu abbia già installato python e pymongo, è solo un semplice elenco da verificare:

import pymongo
from pymongo import MongoClient
client = MongoClient('mongodb://myuser:[email protected]:37017');

db = client['mydb']
col = db.test

col.remove()

col.insert_one({ "a": 1 })

for doc in col.find():
  print(doc)

Che mostra il documento creato ed elencato senza problemi:

{u'a': 1, u'_id': ObjectId('5a08e5e0760108251722a737')}

Nota che in realtà non è necessario menzionare "admin" qui, perché questa è l'impostazione predefinita in cui il driver "si aspetta che siano gli account" e dove "dovresti" davvero farlo.

Ma l'ho fatto nel modo sbagliato

Quindi diciamo che all'inizio ti sei confuso e hai creato l'utente sotto "mydb" invece:

use mydb
db.createUser({ "user": "bert", "pwd": "password", "roles": ["readWrite"] })

Se vai cerca in "admin" quell'utente non c'è. Ma se guardi su "mydb" :

use mydb
db.getUsers()
[
        {
                "_id" : "mydb.bert",
                "user" : "bert",
                "db" : "mydb",
                "roles" : [
                        {
                                "role" : "readWrite",
                                "db" : "mydb"
                        }
                ]
        }
]

In questo modo puoi vedere dove sono ora conservati i dati utente effettivi e come sono stati registrati.

Il caso semplice qui è che "devi" dire a MongoDB da dove ottenere l'autenticazione per questo utente:

client = MongoClient('mongodb://bert:[email protected]:37017/mydb');

Guarda come aggiungiamo "mydb" sulla stringa di connessione. Ecco come si fa.

Questo è in realtà "in corso" per essere reso coerente con TUTTI i driver nel modo in cui vengono effettuate le connessioni e dove avviene l'autenticazione, nonché dove si seleziona il database. Ma ci sono delle regole di base:

  1. Se nessun altro spazio dei nomi del database viene fornito con i dettagli di connessione per le credenziali di autenticazione, allora "admin" è considerato il predefinito .

  2. Se è presente uno spazio dei nomi del database fornito nella stringa di connessione, questo verrà utilizzato per l'autenticazione e questo è l'intento effettivo dello spazio dei nomi del database sulla stringa di connessione.

  3. Sebbene altri driver "attualmente" differiscano nel ruolo dello spazio dei nomi del database nella stringa di connessione, l'utilizzo viene modificato per essere coerente con tutti i driver che "l'utilizzo" di uno spazio dei nomi del database è in realtà una chiamata API, anziché essere assegnato dal stringa di connessione.

Quindi dove devi autenticarti dipende da "dove hai creato l'utente". Ma dovresti davvero notare che "admin" è il luogo in cui "dovresti" farlo invece che altrove.