あなたはここでいくつかの概念を見逃しているように思われるので、私は基本的にあなたが代わりにすべきことへの「ガイド」として答えます。したがって、「認証」は実際には接続の「後に」行うことではなく、実際に認証を試みるときに「適切な場所を探す」必要があります。
これは、基本的に認証の有効化 で概説されているプロセスに従うことで開始できます。 コアドキュメントからですが、この「テスト」を自分のユーザーアカウントとローカルディレクトリで実行したいため、特に変更されています。
改訂手順-ドキュメントから直接
したがって、最初にローカルの作業ディレクトリを選択し、その下にデータベースストレージファイルのパスを作成する必要があります。 * nixベースのシステムでは、次のようなことができます。
mkdir -p scratch/data/db
cd scratch
次に、他のオプションなしで別のMongoDBインスタンスを起動します。ポートが他の実行中のインスタンスと競合しないことを確認します:
mongod --port 37017 --dbpath data/db
新しいターミナルまたはコマンドラインウィンドウで、シェルに接続できます。
mongo --port 37017
管理者権限を持つ少なくとも1つのアカウントで、少なくとも「アカウントを作成」し、問題が発生した場合にアカウントを変更する必要があるため、次のアカウントを作成します。
use admin
db.createUser(
{
user: "admin",
pwd: "admin",
roles: [{ role: "userAdminAnyDatabase", db: "admin" }]
}
)
次に、シェルを終了し、既存のmongod
を閉じます。 インスタンスが他のターミナルまたはコマンドプロンプトで実行されている場合は、--auth
を使用してインスタンスを再起動します。 :
mongod --auth --port 37017 --dbpath data/db
特定のユーザー-必ずこれらに従ってください
ここで、実際に「アプリケーションで使用される」ユーザーを作成する必要があります。したがって、これらの手順は、正しく実行するために重要です。
「管理ユーザー」を使用してシェルにログインします:
mongo -u admin -p admin --port 37017 --authenticationDatabase 'admin'
または、db.auth()
を実行することもできます 質問に示されている方法ですが、前述のように、これは必須 "admin"
で承認される 名前空間。
次に実行したいのは、"mydb"
にアクセスできるユーザーを作成することです。 readWrite
の名前空間として 役割。キックの場合は、このユーザーにreadAnyDatabase
を持たせることもできます。 実際に他に何もできない場合でも、すべてのデータベース名前空間を「リスト」できるようにします。
use admin
db.createUser(
{
"user": "myuser",
"pwd": "password",
"roles": [
{ "role": "readWrite", "db": "mydb" },
"readAnyDatabase"
]
}
)
追加の出力のために、現在作成されているユーザーを見てみましょう:
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"
}
]
}
]
これらが命名でどのように拡張されたか、特にさまざまな"db"
に割り当てられた値を確認してください 各ユーザーのキー。これにより、MongoDBがこれをどのように検索するか、およびその理由についてもう少し洞察が得られるはずです。
Python接続
最後に、Pythonから接続したいだけです。したがって、Pythonとpymongoがすでにインストールされていると仮定すると、確認するための簡単なリストになります。
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)
これは、問題なく作成および一覧表示されたドキュメントを示しています:
{u'a': 1, u'_id': ObjectId('5a08e5e0760108251722a737')}
"admin"
について実際に言及する必要はないことに注意してください。 これは、ドライバーが「アカウントを期待する」デフォルトであり、実際に「実行する」必要があるためです。
しかし、私はそれを間違った方法で行いました
つまり、元々混乱していて、"mydb"
の下にユーザーを作成したとしましょう。 代わりに:
use mydb
db.createUser({ "user": "bert", "pwd": "password", "roles": ["readWrite"] })
"admin"
を調べてください そのユーザーはそこにいません。しかし、"mydb"
を見ると :
use mydb
db.getUsers()
[
{
"_id" : "mydb.bert",
"user" : "bert",
"db" : "mydb",
"roles" : [
{
"role" : "readWrite",
"db" : "mydb"
}
]
}
]
したがって、実際のユーザーデータが現在どこに保存され、どのように記録されているかを確認できます。
ここでの単純なケースは、このユーザーの認証をどこから取得するかをMongoDBに「指示する」必要がある場合です。
client = MongoClient('mongodb://bert:[email protected]:37017/mydb');
"mydb"
を追加する方法をご覧ください 接続文字列に移動します。これがその方法です。
これは実際には「進行中」であり、接続の確立方法、認証の実行場所、およびデータベースの選択場所において、すべてのドライバーと一貫性を保つようになっています。ただし、基本的なルールがあります:
-
認証資格情報の接続の詳細が他のデータベース名前空間に提供されていない場合は、
"admin"
デフォルトと見なされます 。 -
接続文字列にデータベース名前空間が指定されている場合、これは認証に使用されます これは、接続文字列でのデータベース名前空間の実際の意図です。
-
他のドライバーは「現在」接続文字列でのデータベース名前空間の役割が異なりますが、データベース名前空間を「使用する」ことは実際にはAPI呼び出しであり、から割り当てられるのではなく、すべてのドライバーと一致するように使用法が変更されています。接続文字列。
したがって、認証が必要な場所は、「ユーザーを作成した場所」によって異なります。ただし、"admin"
に注意する必要があります。 他の場所ではなく、これを「行うべき」場所です。