Je lijkt hier een aantal concepten te missen, dus ik zal in feite antwoorden als een "gids" voor wat je in plaats daarvan zou moeten doen. Dus "authenticatie" is niet echt iets dat u "na" de verbinding doet, maar u moet "op de juiste plaats zoeken" wanneer u daadwerkelijk probeert te authenticeren.
We kunnen hiermee beginnen door in wezen het proces te volgen dat wordt beschreven in Autorisatie inschakelen uit de kerndocumentatie, maar specifiek gewijzigd omdat u deze "test" onder uw eigen gebruikersaccount en lokale directory wilt uitvoeren.
Revisiestappen - rechtstreeks uit documentatie
Dus zou eerst een lokale werkdirectory willen kiezen en een pad maken voor de databaseopslagbestanden daaronder. Op *nix-gebaseerde systemen kun je zoiets doen als:
mkdir -p scratch/data/db
cd scratch
Vervolgens willen we een afzonderlijke MongoDB-instantie opstarten zonder andere opties. Ervoor zorgen dat de poort niet conflicteert met een andere actieve instantie:
mongod --port 37017 --dbpath data/db
In een nieuw terminal- of opdrachtregelvenster kunt u vervolgens verbinding maken met de shell:
mongo --port 37017
U wilt altijd ten minste één account met beheerdersrechten om ten minste "accounts aan te maken" en deze te wijzigen voor het geval u in de problemen komt, dus maak er een aan:
use admin
db.createUser(
{
user: "admin",
pwd: "admin",
roles: [{ role: "userAdminAnyDatabase", db: "admin" }]
}
)
Verlaat nu de shell en sluit de bestaande mongod
instantie die in de andere terminal of opdrachtprompt wordt uitgevoerd en vervolgens opnieuw start met --auth
:
mongod --auth --port 37017 --dbpath data/db
Specifieke gebruiker - Zorg ervoor dat u deze volgt
Nu wilt u eigenlijk een gebruiker maken die "door uw toepassing wordt gebruikt". Deze stappen zijn dus belangrijk om ervoor te zorgen dat u het goed doet.
Log in op een shell met uw "adminstratieve gebruiker":
mongo -u admin -p admin --port 37017 --authenticationDatabase 'admin'
U kunt ook de db.auth()
methode zoals getoond in de vraag, maar zoals opgemerkt moet dit moet geautoriseerd zijn op de "admin"
naamruimte.
Het volgende dat u wilt doen, is een gebruiker maken met toegang tot "mydb"
als een naamruimte met de readWrite
rol. Voor de kick gaan we deze gebruiker ook de readAnyDatabase
. geven waardoor ze de naamruimten van alle databases kunnen "lijsten", als ze er eigenlijk niets anders mee kunnen doen.
use admin
db.createUser(
{
"user": "myuser",
"pwd": "password",
"roles": [
{ "role": "readWrite", "db": "mydb" },
"readAnyDatabase"
]
}
)
Laten we voor extra output eens kijken naar de huidige aangemaakte gebruikers:
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"
}
]
}
]
Zie hoe deze zijn uitgebreid in naamgeving, en met name de waarden die zijn toegewezen aan de verschillende "db"
sleutels op elke gebruiker. Dit zou je wat meer inzicht moeten geven in hoe MongoDB dit opzoekt en waarom.
Python-verbinding
Eindelijk willen we gewoon verbinding maken vanuit python. Dus in de veronderstelling dat je python en pymongo al hebt geïnstalleerd, dan is het gewoon een simpele lijst om te verifiëren:
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)
Dat toont het document dat zonder problemen is gemaakt en weergegeven:
{u'a': 1, u'_id': ObjectId('5a08e5e0760108251722a737')}
Merk op dat we eigenlijk geen melding hoeven te maken van "admin"
hier, omdat dit de standaardinstelling is waar de bestuurder "verwacht dat de accounts zijn" en waar u het echt "zou moeten doen".
Maar ik deed het op de verkeerde manier
Dus laten we zeggen dat je oorspronkelijk helemaal in de war was en de gebruiker onder "mydb"
. hebt aangemaakt in plaats daarvan:
use mydb
db.createUser({ "user": "bert", "pwd": "password", "roles": ["readWrite"] })
Als je gaat kijken in "admin"
die gebruiker is er niet. Maar als je kijkt op "mydb"
:
use mydb
db.getUsers()
[
{
"_id" : "mydb.bert",
"user" : "bert",
"db" : "mydb",
"roles" : [
{
"role" : "readWrite",
"db" : "mydb"
}
]
}
]
U kunt dus zien waar de daadwerkelijke gebruikersgegevens nu worden bewaard en hoe deze zijn vastgelegd.
Het eenvoudige geval hier is dat u MongoDB "moet" vertellen waar u de authenticatie voor deze gebruiker kunt verkrijgen:
client = MongoClient('mongodb://bert:[email protected]:37017/mydb');
Bekijk hoe we "mydb"
toevoegen op de verbindingsreeks. Dit is hoe het moet.
Dit is in feite "in uitvoering" om consistent te worden gemaakt met ALLE stuurprogramma's in hoe verbindingen worden gemaakt en waar authenticatie plaatsvindt, evenals waar u de database selecteert. Maar er zijn basisregels:
-
Als er geen andere databasenaamruimte is voorzien van verbindingsdetails voor authenticatiegegevens, dan
"admin"
wordt beschouwd als de standaard . -
Als er een databasenaamruimte is opgegeven in de verbindingsreeks, deze wordt gebruikt voor authenticatie en dit is de werkelijke bedoeling van de databasenaamruimte op de verbindingsreeks.
-
Hoewel andere stuurprogramma's "momenteel" verschillen in de rol van de databasenaamruimte op de verbindingsreeks, wordt het gebruik gewijzigd om consistent te zijn met alle stuurprogramma's dat het "gebruiken" van een databasenaamruimte in feite een API-aanroep is, in plaats van te worden toegewezen vanuit de verbindingsreeks.
Dus waar je moet authenticeren hangt af van "waar je de gebruiker hebt gemaakt". Maar je moet echt opmerken dat "admin"
is de plaats waar u dit "zou" moeten doen in plaats van ergens anders.