我发现问题出在什么时候,问题发生了,但我不明白为什么会发生......
这是我的app.js,这里没有问题,我测试了10次以上:
'use strict';
const Joi = require('joi');
Joi.objectId = require('joi-objectid')(Joi);
const config = require('config');
const mongoose = require('mongoose');
const debug = require('debug')('app:api');
const express = require('express');
const path = require('path');
const morgan = require('morgan');
const bodyParser = require('body-parser');
const { isNotFound, errorHandlerDev, errorHandlerPro } = require('./middleware/handlers');
const index = require('./routes/index');
const auth = require('./routes/auth');
const users = require('./routes/users');
const app = express();
if(!config.get('jwtPrivateKey')) {
console.log('KRİTİK HATA: JWT Private Key Tanımlanmadı!');
process.exit(1);
}
if(!config.get('connectionString')) {
console.log('KRİTİK HATA: Connection String Tanımlanmadı!');
process.exit(1);
}
if(!process.env.USERNAME || !process.env.PASSWORD) {
console.log('KRİTİK HATA: MongoDB Kullanıcı Bilgileri Eksik!');
process.exit(1);
}
mongoose.connect(config.get('connectionString').replace(/({{USERNAME}}|{{PASSWORD}})/gi, match => { match = match.replace(/({|})/gi, symbol => ''); return process.env[match]; }))
.then(() => debug('MongoDB > Uptime-Monitor Başarıyla Bağlandı!'))
.catch(error => debug('MongoDB > Uptime-Monitor Bağlanırken Hata Oluştu! Hata Bilgisi:', error));
app.use(morgan('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use('/api/', index);
app.use('/api/auth', auth);
app.use('/api/users', users);
app.use(isNotFound);
if (app.get('env') === 'development') {
app.use(errorHandlerDev);
}
app.use(errorHandlerPro);
app.set('port', process.env.PORT || 5000);
app.listen(app.get('port'), function () {
debug(`Express Sunucusu Port ${app.get('port')} Üzerinde Çalışıyor!`);
});
这是我的用户模型文件user.js:
'use strict';
const config = require('config');
const jwt = require('jsonwebtoken');
const Joi = require('joi');
Joi.objectId = require('joi-objectid')(Joi);
const mongoose = require('mongoose');
var model = {};
// Required Data: username, email, phone, password
// Optional Data: name, lastname, tosAgreement, isAdmin
model.userSchema = new mongoose.Schema({
name: {
type: String,
trim: true,
minlength: [3, 'Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 50 Adet Karakterden Oluşabilir.'],
maxlength: [50, 'Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 50 Adet Karakterden Oluşabilir.']
},
lastname: {
type: String,
trim: true,
minlength: [3, 'Soyadınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 50 Adet Karakterden Oluşabilir.'],
maxlength: [50, 'Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 50 Adet Karakterden Oluşabilir.']
},
username: {
type: String,
trim: true,
minlength: [3, 'Kullanıcı Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 30 Adet Karakterden Oluşabilir.'],
maxlength: [20, 'Kullanıcı Adınızın Karakter Sayısı Uygun Değildir. Minimum 3, Maksimum 30 Adet Karakterden Oluşabilir.'],
//unique: [true, 'İstenilen Kullanıcı Adı Daha Önce Kullanılmış.'],
validate: {
validator: function(v) {
let re = /^\w+$/;
return re.test(v);
},
message: 'Uygun Kullanıcı Adı Giriniz.'
},
match: [/^\w+$/, 'Uygun Kullanıcı Adı Giriniz.']
},
email: {
type: String,
trim: true,
//unique: [true, 'İstenilen E-Posta Adresi Daha Önce Kullanılmış.'],
lowercase: true,
validate: {
validator: function(v) {
let re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
return re.test(v);
},
message: 'Uygun E-Posta Adresi Giriniz.'
},
match: [/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/, 'Uygun E-Posta Adresi Giriniz.']
},
phone: {
type: Number,
required: [true, 'Telefon Numaranızı Girmeniz Gerekmektedir.'],
//unique: [true, 'İstenilen Telefon Numarası Daha Önce Kullanılmış.'],
min: [10, 'Telefon Numaranızın Uzunluğu Uygun Değildir. 10 Haneden Oluşmalıdır.'],
},
password: {
type: String,
trim: true,
required: [true, 'Şifrenizi Girmeniz Gerekmektedir.'],
minlength: 5,
maxlength: 1024
},
registerDate: {
type: Date,
default: Date.now
},
tosAgreement: {
type: Boolean,
default: true
},
isAdmin: {
type: Boolean,
required: true,
default: false
}
});
model.userSchema.methods.generateToken = function() {
return jwt.sign({ _id: this._id, isAdmin: this.isAdmin}, config.get('jwtPrivateKey'));
};
model.User = mongoose.model('User', model.userSchema);
model.validate = user => {
const Schema = {
name: Joi.string().min(3).max(50),
lastname: Joi.string().min(3).max(50),
username: Joi.string().required().regex(/^\w+$/).min(3).max(20),
email: Joi.string().required().min(3).email(),
phone: Joi.number().required().min(10),
password: Joi.string().required().min(5).max(255),
tosAgreement: Joi.boolean().default(true),
isAdmin: Joi.boolean().default(false)
};
return Joi.validate(user, Schema);
};
model.validateId = id => {
return Joi.validate(id, Joi.objectId().required());
};
module.exports.model = model;
最后,我的users.js,api / users路由器,这里也没有问题:
'use strict';
const auth = require('./../middleware/auth');
const admin = require('./../middleware/admin');
const bcyript = require('bcrypt');
const _ = require('lodash');
const mongoose = require('mongoose');
const { userSchema, User, validate, validateId } = require('./../models/user');
const express = require('express');
const router = express.Router();
router.get('/', [auth, admin], async (req, res) => {
const users = await User.find().select({ _id: 1, name: 1, email: 1, tosAgreement: 1}).sort({ name: 1 });
if(!users) return res.status(200).send({'BİLGİ': 'Hiç Kullanıcı Bulunamadı.'});
res.status(200).send(users);
});
router.get('/me', auth, async (req, res) => {
const user = await User.findById(req.user._id).select('-password -phone');
res.status(200).send(user);
});
router.get('/:id', [auth, admin], async (req, res) => {
const user = await User.findById(req.params.id).select({ _id: 1, name: 1, email: 1, tosAgreement: 1, isAdmin: true});
if(!user) return res.status(404).send({'HATA': 'Belirtilen ID\'ye Sahip Kullanıcı Bulunamadı.'});
res.status(200).send(user);
});
router.post('/', /*[auth, admin],*/async (req, res) => {
const { error } = validate(req.body);
if(error) return res.status(400).send({'Hata': error.details[0].message});
let isAnyUserWithThatEmail = await User.findOne({ email: req.body.email });
if(isAnyUserWithThatEmail) return res.status(400).send({'Hata': 'Belirtilen E-Posta Adresi Kullanımda.'});
let isAnyUserWithThatPhone = await User.findOne({ phone: req.body.phone });
if(isAnyUserWithThatPhone) return res.status(400).send({'Hata': 'Belirtilen Telefon Numarası Kullanımda.'});
const user = new User(req.body);
const salt = await bcyript.genSalt(10);
user.password = await bcyript.hash(user.password, salt);
await user.save();
const token = user.generateToken();
res.header('x-auth-token', token).status(201).send(_.pick(user, ['_id', 'name', 'email', 'tosAgreement', 'isAdmin']));
});
router.put('/:id', auth, async (req, res) => {
const errorId = validateId(req.params.id).error;
if(errorId) return res.status(400).json({'Hata': errorId.details[0].message});
const { error } = validate(req.body);
if(error) return res.status(400).send({'Hata': error.details[0].message});
const salt = await bcyript.genSalt(10);
const user = await User.findByIdAndUpdate(req.params.id, {
name: req.body.name,
lastname: req.body.lastname,
email: req.body.email,
phone: req.body.phone,
password: await bcyript.hash(req.body.password, salt),
tosAgreement: req.body.tosAgreement,
isAdmin: req.body.isAdmin
}, { new: true, runValidators: true });
if(!user) return res.status(404).send({'Hata': 'Belirtilen ID\'ye Sahip Kullanıcı Bulunamadı.'});
res.status(200).send(_.pick(user, ['_id', 'name', 'email', 'tosAgreement', 'isAdmin']));
});
router.delete('/:id', [auth, admin], async (req, res) => {
const { error } = validateId(req.params.id);
if(error) return res.status(400).json({'Hata': error.details[0].message});
const user = await User.findByIdAndRemove(req.params.id);
if(!user) return res.status(404).send({'Hata': 'Belirtilen ID\'ye Sahip Kullanıcı Bulunamadı.'});
res.status(200).send(_.pick(user, ['_id', 'name', 'email', 'tosAgreement', 'isAdmin']));
});
module.exports = router;
"错误:检测到循环依赖。"取消注释" unique:true"在我的模型(user.js)上。当我评论" unique:true"线条,它消失了。问题出在这里,但为什么呢?我需要使用唯一标识符。
//@@@ NO ERROR WHEN COMMENT OUT THESE 'unique' IDENTIFIERS @@@
...
username: {
...
//unique: [true, 'İstenilen Kullanıcı Adı Daha Önce Kullanılmış.'],
...
},
email: {
...
//unique: [true, 'İstenilen E-Posta Adresi Daha Önce Kullanılmış.'],
...
},
phone: {
...
//unique: [true, 'İstenilen Kullanıcı Adı Daha Önce Kullanılmış.'],
...
}
...
答案 0 :(得分:2)
我至少找到了解决方案, 我做了一些研究,发现了' index'字段或猫鼬的概念。我们需要在Schema上设置索引以使其唯一。
model.userSchema = new mongoose.Schema({
...
username: {
...
index: true,
unique: [true, 'İstenilen Kullanıcı Adı Daha Önce Kullanılmış.'],
...
},
email: {
...
index: true,
unique: [true, 'İstenilen E-Posta Adresi Daha Önce Kullanılmış.'],
...
},
phone: {
...
index: true,
unique: [true, 'İstenilen Kullanıcı Adı Daha Önce Kullanılmış.'],
...
}
...
});
model.userSchema.set('autoIndex', false); // REQUIRED FOR UNIQUE INDEX AND INDEX IDENTIFIERS