문제

사용자 로그인을 확인하는 이와 같은 SQL 문이 있다고 가정 해 봅시다.

SELECT * FROM users 
WHERE username='test@example.com', password='abc123', expire_date>=NOW();

SQL에는 각 조건을 자체 쿼리로 분리하고 개별적으로 테스트 할 필요없이 조건이 어디에서 실패하는지 구체적으로 결정하는 방법이 있습니까?

이 특정 예에서는 개발자가 사용자에게 로그인 시도가 실패한 이유를 정확하게 알려줄 수 있습니다.

내 목적을 위해 PHP/MySQL을 사용하고 있습니다.

도움이 되었습니까?

해결책 5

다음은 다음과 같이 생각해 냈습니다.

SELECT
  IF(mem_username='test@example.com','true','Error: Bad Username') AS mem_username,
  IF(mem_password ='abc123','true','Error: Bad Password') AS mem_password'
FROM MEMBERS
WHERE mem_username='test@example.com' AND mem_password='abc123'

이렇게하면 오류 메시지를 코드로 감지 한 다음 필요에 따라 표시 할 수 있습니다.

노트: 예제 코드에 대한 보안 문제를 인용하는 모든 분들께 우려 해 주셔서 감사합니다. 그러나 이것은 실제 생산 코드가 아닙니다. 이것은 단순히 내가 가진 질문을 보여주는 간단한 예였습니다. 비밀번호를 명확한 텍스트로 저장해서는 안되며 로그인이 실패하는 이유에 대한 사용자 구체적인 정보를 제공해서는 안된다는 것은 분명합니다.

다른 팁

글쎄, 당신이 할 수있는 한 가지는 쿼리를 변경하여 사용자 이름에서만 일치하는 것입니다. 그런 다음 코드에서 비밀번호와 만료 날짜를 확인하여 적절한 오류를 반환합니다.

또한 예제 쿼리가 단순화되기를 바랍니다. 확실히 당신은 비밀번호를 소금/암호화/해시해야하며, 특정 기간 내에 실패한 시도 횟수를 제한하는 것을 포함해야합니다 ...

실제 질문 (원하는 결과와 반대로)에 관한 한, Where 절에서 해당 정보를 얻을 수있는 방법은 없습니다. 당신이 할 수있는 가장 가까운 것은 다음과 같습니다.

SELECT *,
    CASE WHEN Password = 'asdf' THEN 1 ELSE 0 END AS IsPasswordMatch,
    CASE WHEN Expiration >= NOW() THEN 1 ELSE 0 END AS IsActiveAccount
FROM Users
WHERE Username = 'user'

MySQL에서는 선택 목록에 부울 표현을 넣을 수 있습니다. 부울 표현식은 정수 1을 평가할 때 또는 정수 0을 거짓으로 평가합니다.

SELECT password = 'abc123' AS is_authenticated,
       expire_date >= NOW() AS is_not_expired
FROM users
WHERE username='test@example.com';

노트: 다른 브랜드의 RDBMS에서 작동하는 쿼리를 작성 해야하는 경우, 부울 표현을 사용하는 것은 비표준입니다. 사용 CASE 다른 사람들이 게시 한 구문.

추신 : 이것은 당신의 질문에서 접하는 것이지만, 나는 당신이 비밀번호를 일반 텍스트로 저장하지 말 것을 촉구합니다. 소금에 절인 암호의 해시 다이제스트를 저장하십시오. 보다 암호 소금은 무지개 테이블 공격에 어떻게 도움이됩니까?

아니요, Where-Clause는 블록으로 적용되며 모든 행을 스캔 할 필요는 없도록 다양한 기술이 사용됩니다. 또한, 어떤 행이 원하는지를 어떻게 알 수 있습니까?

또한 로그인 시도가 실패한 이유에 대해 사용자에게 너무 많이 알리고 싶지 않을 것입니다. 너무 많이 말하면 계정 마이닝 및 비밀번호 공격과 같은 악용이 가능합니다.

편집하다 이를 사용자에게 진정으로 표시하려면 로직을 다른 부분으로 나누십시오.

  1. 신원을 검증하십시오
    조치 : 데이터베이스에서 해당 사용자 행을 가져 오기
    결과:
    • 그러한 행이 존재하지 않으면 => 유효하지 않은 계정
    • 행이 반환되면 2 단계로 계속하십시오.
  2. 자격 증명을 확인하십시오
    조치 : 자격 증명이 저장되는 것과 같은 방식으로 처리 된 제공된 비밀번호에 대해 저장된 자격 증명 (비밀번호, 암호 해시 또는 암호화 된 암호)을 확인하십시오.
    결과:
    • 일치하지 않음 => 유효하지 않은 암호 / 자격 증명
    • match => 성공적인 로그인 시도
  3. 로그인 사용자
    조치 : 세션 등에 데이터 추가

아마도 where 절의 부분을 '및'로 분리하면됩니다.

SELECT * FROM users 
WHERE username='test@example.com'
   And password='abc123'
   And expire_date>=NOW();
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top