ExpressJS 응용 프로그램의 Bookshelf 사용자 모델에 매우 기본적인 로그인 방법을 추가하고 있지만 User 모델의 로그인 함수가 반환하는 거부 된 오류로부터 오류를 잡을 수는 없습니다. . 나는 Books shelf의 예제 로그인을 http://bookshelfjs.org/#Model-static-extend의 docs에서보고 있지만이 예제에서는 Bluebird를 사용하고 있지만 반면에 내장 된 ES6 약속과 동일한 작업을 수행하려고합니다. 사용자 모델에서ES6 약속 및 BookshelfJS 오류 잡기
내 로그인 방법 :
userModel.js
function login(email, password) {
return new Promise((resolve, reject) => {
User.where('email', email)
.fetch({ require: true })
.then(user => {
bcrypt.compare(password, user.get('password'), (err, matched) => {
if (!matched) return reject(new Error('Password didn\'t match!'));
resolve(user);
});
});
});
로그인을 구현하고 책장 User
모델 User.login
를 호출하는 컨트롤러 액션 :
usersAuthController. js
function logUserIn(req, res) {
new User().login(req.body.email, req.body.password)
.then(user => res.json({ message: 'Login succeeded!' }))
.catch(User.NotFoundError,() => res.status(404).json({ error: 'User not found!' }) // catch #1
.catch(err => res.status(401).json({ err: err.message })); // catch #2
}
내 생각에 은 Bookshelf의 User.fetch
메서드가 주어진 전자 메일을 가진 사용자를 찾을 수 없을 때 거부 된 약속을 반환 할 수 있습니다. 이 경우 .catch(User.NotFoundError ...)
(catch # 1) 줄이이를 catch하고 404를 반환해야합니다. 에 전달 된 암호가 사용자의 암호와 일치하지 않는다고 판단한 경우 bcrypt
에서 거부 된 약속을 반환 할 수도 있습니다. 내가 잘못된 암호를 넣으면 "포괄"(2 캐치 #)를 User.NotFoundError
catch 문 아래는 401
를 반환해야합니다, 위의 코드에서 logUserIn()
컨트롤러 액션 오류 메시지 { error: "Cannot set property 'message' of undefined" }
과 # 2를 잡아 간다 메시지 대신 login()
에 거절 한 메시지. 존재하지 않는 이메일을 넣으면 응답이 전송되지 않고 콘솔에 오류 Unhandled rejection CustomError: EmptyResponse
이 표시됩니다. 유효한 입력 만 작동합니다.
수정 시도 :User.NotFoundError
을 모델에 직접 붙잡고 있습니다.
userModel.js
function login(email, password) {
return new Promise((resolve, reject) => {
User.where('email', email)
.fetch({ require: true })
.then(user => {
bcrypt.compare(password, user.get('password'), (err, matched) => {
if (!matched) return reject(new Error('Password didn\'t match!'));
resolve(user);
});
})
.catch(User.NotFoundError,() => reject({ error: 'User not found!' }));
});
이 방법은, 내가 모두 오류 (잘못된 암호를 잡을 수 : 로그인 방법은 지금처럼 보이도록
나는 사용자 모델에 캐치 # 1을 이동 존재하지 않는 전자 메일)을 올바르게 입력했는데 컨트롤러에서 상태 코드를 지정할 수 없습니다. 주어진 이메일을 가진 사용자를 찾을 수 없다면 404를 반환해야하지만 비밀번호가 틀린 경우 401을 반환해야하지만 두 오류는 모두 catch-all (catch # 2)로 이동해야합니다. 컨트롤러 동작 (항상 401을 반환).
이 문제를 해결하려면User
모델에서 나는
.catch(User.NotFoundError,() => reject({ name: 'NotFoundError', message: 'User not found!' }))
을 할 수있는 컨트롤러의 행동에 나는
const statusCode = err.name === 'NotFoundError' ? 404 : 401
으로지고있어 오류의 종류를 확인할 수 있지만 정말 더러워 보인다 이러한
.catch
문을 갖는 지점이 골대를 벗어났습니다 .
에있는 모델의 로그인 방법 및 기타 오류에서 User.NotFoundError
을 잡을 방법이 있습니까? 왜 내가 처음에 설치 한 설정이 usersAuthController에 catch
문을 모두 가지고있는 것은 아닙니다.js이고 Cannot set property 'message' of undefined'
과 CustomError: EmptyResponse
오류는 무엇을 의미합니까? (이것은 Bookshelf의 Bluebird 약속을 섞어 놓는 것과 내장 된 ES6 약속을 비교하는 것과 관련이 있습니까?) 이것을 처리하는 가장 좋은 방법은 무엇입니까?
이 피 ['Promise' 생성자 안티 패턴 (http://stackoverflow.com/q/23803743/1048572)! 'login' 함수 내에서만'bcrypt.compare'를 promisify해야합니다. – Bergi