sql >> Base de Datos >  >> NoSQL >> MongoDB

Autenticar después de elegir la base de datos

Parece que te faltan algunos conceptos aquí, así que básicamente responderé como una "guía" de lo que deberías estar haciendo. Por lo tanto, la "autenticación" no es realmente algo que haga "después" de la conexión, sino que debe "buscar en el lugar correcto" cuando realmente intenta autenticarse.

Podemos comenzar esto esencialmente siguiendo el proceso descrito en Habilitar autenticación de la documentación principal, pero alterado específicamente porque desea ejecutar esta "prueba" en su propia cuenta de usuario y directorio local.

Pasos de revisión:directamente desde la documentación

Entonces, primero querría elegir un directorio de trabajo local y hacer una ruta para los archivos de almacenamiento de la base de datos debajo de eso. En sistemas basados ​​en *nix puedes hacer algo como:

mkdir -p scratch/data/db
cd scratch

Luego queremos iniciar una instancia MongoDB separada sin ninguna otra opción. Asegurarse de que el puerto no entre en conflicto con ninguna otra instancia en ejecución:

mongod --port 37017 --dbpath data/db

En una nueva terminal o ventana de línea de comandos, puede conectarse al shell:

mongo --port 37017

Siempre desea al menos una cuenta con privilegios administrativos para al menos "crear cuentas" y modificarlas en caso de que tenga problemas, así que cree una:

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

Ahora salga del shell y cierre el mongod existente instancia ejecutándose en la otra terminal o símbolo del sistema y luego inícielo nuevamente usando --auth :

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

Usuario específico:asegúrese de seguir estos

Ahora realmente desea crear un usuario que será "utilizado por su aplicación". Por lo tanto, estos pasos son importantes para asegurarse de hacerlo bien.

Inicie sesión en un shell usando su "usuario administrativo":

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

Alternativamente, puede hacer db.auth() método como se muestra en la pregunta, pero como se indica, esto debe estar autorizado en el "admin" espacio de nombres.

Lo siguiente que debe hacer es crear un usuario con acceso a "mydb" como espacio de nombres con readWrite role. Por diversión, también vamos a permitir que este usuario tenga el readAnyDatabase permitiéndoles "enumerar" todos los espacios de nombres de las bases de datos, si no pueden hacer nada más con ellos.

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

Solo para resultados adicionales, veamos los usuarios creados actualmente:

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"
                        }
                ]
        }
]

Vea cómo estos se han expandido en la denominación y, en particular, los valores asignados a los distintos "db" claves en cada usuario. Esto debería darle un poco más de información sobre cómo MongoDB busca esto y por qué.

Conexión Python

Finalmente solo queremos conectarnos desde python. Entonces, suponiendo que ya tiene Python y Pymongo instalados, entonces es solo una lista simple para verificar:

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)

Que muestra el documento creado y listado sin problema:

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

Tenga en cuenta que en realidad no necesitamos hacer ninguna mención de "admin" aquí, porque este es el lugar predeterminado donde el conductor "espera que estén las cuentas" y donde realmente "debería" hacerlo.

Pero lo hice mal

Así que digamos que originalmente te confundiste y creaste el usuario bajo "mydb" en cambio:

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

Si vas busca en "admin" ese usuario no esta. Pero si miras en "mydb" :

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

Para que pueda ver dónde se guardan ahora los datos reales del usuario y cómo se han registrado.

El caso simple aquí es que "debe" decirle a MongoDB de dónde obtener la autenticación para este usuario:

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

Vea cómo agregamos "mydb" en la cadena de conexión. Así es como se hace.

En realidad, esto está "en progreso" para ser consistente con TODOS los controladores en cómo se realizan las conexiones y dónde ocurre la autenticación, así como también dónde selecciona la base de datos. Pero hay reglas básicas:

  1. Si no se proporciona ningún otro espacio de nombres de base de datos con detalles de conexión para las credenciales de autenticación, "admin" se toma como predeterminado .

  2. Cuando se proporcione un espacio de nombres de base de datos en la cadena de conexión, se usará para la autenticación y esta es la intención real del espacio de nombres de la base de datos en la cadena de conexión.

  3. Aunque otros controladores "actualmente" difieren en la función del espacio de nombres de la base de datos en la cadena de conexión, el uso se está cambiando para ser coherente con todos los controladores que "usar" un espacio de nombres de base de datos es de hecho una llamada API, en lugar de ser asignado desde el cadena de conexión.

Entonces, dónde necesita autenticarse depende de "dónde creó el usuario". Pero realmente deberías tener en cuenta que "admin" es el lugar donde "debería" estar haciendo esto en lugar de en cualquier otro lugar.