2010-01-09 3 views
16

사용자가 가입하는 PHP 웹 사이트를 만들고 있는데 "전자 메일 확인"코드에 대한 모범 사례가 궁금합니다.전자 메일 확인 코드에 대한 유용한 정보

신규 사용자는 전자 메일 주소를 확인해야합니다. 코드를 생성하여 사용자에게 전자 메일로 보냄으로써 전자 메일 주소를 확인한 다음 전자 메일 주소를 사용하여 계정을 활성화 할 수 있습니다. 오히려 데이터베이스에이 키를 저장하는 대신, 나는 쉽고 간단한 해결 방법을 사용하고 있습니다 : 코드의 결과입니다

$ 타임 스탬프가 사용자 생성 시간을 의미
md5("xxxxxxxxx".$username."xxxxxxxxxxx".$timestamp."xxxxxxxxx"); 

. 전체적으로 나는 이것에 상당히 만족하고 있었지만, 생각해 보았습니다. 충분히 안전합니까? 그리고 충돌의 가능성은 어떻습니까? 암호 재설정 등을위한 코드를 생성해야합니다. 비슷한 방법을 사용하면 충돌로 인해 한 사용자가 부주의로 다른 사용자의 비밀번호를 재설정 할 수 있습니다. 그리고 그것은 좋지 않습니다.

어떻게 이런 일을합니까? 내 생각은 다음과 같은 형식의 테이블했다 '유형'1, 2, 3의 의미 "활성화", "이메일 변경"또는 "암호 재설정"것

codePK (int, a-I), userID (int), type (int), code (varchar 32), date (timestamp) 

. 이것이 좋은 방법인가요? 더 좋은 방법이 있습니까?

위와 유사한 방법을 사용하면 cron-jobs를 사용하지 않고 2 일 이상 된 항목을 자동으로 삭제할 수 있습니까? 내 호스트 (nearlyfreespeech.net)는 지원하지 않습니다. 가능하다면 wget이 일을 삭제하는 스크립트 인 외부 호스트에서 cron-job을 사용하는 것을 피하고 싶습니다.

감사합니다.
말라

업데이트 :
명확히하기 위해 : 나는 원래 기능을 피하기 위해 노력했다있는 데이터베이스를 사용하는 것입니다 안전하고 안전하게이 작업에 대해 갈 수있는 유일한 방법을 깨달았다. 내 질문은 테이블 (또는 테이블)을 구성하는 방법에 관한 것입니다. 누군가 제가 codePK를 없애고 코드를 PK로 만들 것을 제안했습니다. 간단히 말해, 제 질문은 당신이하는 일입니까?

+0

전자 메일 확인 코드에 대한 유용한 정보가 있습니까? 그들을 퇴장 시키십시오. – Leo

+1

비밀번호 리셋을 위해서만 사용자가 유효한 이메일 주소를 가지고 있어야합니다. 우리가 다루는 실제 세계는 "사용자의 책임입니다"라고 주장 할 수는 있지만 ... "암호를 절대 잊지 않을"사람이 암호를 잊어 버리 자마자, 아마도 1 ~ 2 주 안에 시스템은 "멍청한"것입니다. – Mala

답변

10

나는 트릭 이러한 종류의 필요 그것은 모두 당신에 의해 언급, 일반적으로 두 가지 이유 중 하나 일 때 :에 사용되는 키로서 사용자

  • 로 전송 확인 메일에 사용되는 키로서

    1. 비밀번호 재설정 링크

    물론 이러한 구성의 사용을 고려할만한 다른 경우가있을 수 있습니다.

    우선 무엇보다도 숨겨진 소금을 사용해야하며 알고있을뿐입니다. 이 소금은 각 사용자마다 달라야합니다. 소금은 예를 들어 sha256(something random)으로 계산 될 수 있습니다. 이 소금은 사용자 이름과 암호 (소금으로 해시 된)와 함께 데이터베이스에 저장되어야합니다.

    비밀번호 재설정 링크를 보낼 때 나는 다른 소금을 만들 것입니다 (사용자가 소금으로 해시 한 물건에 대한 액세스를 제공하지 마십시오. 그는 비밀번호를 알고 있기 때문에 소금을 알아낼 수 있습니다) . 근본적으로 무작위 문자열의 해시 인 다른 소금 (길이가 문제라고 언급 했으므로 여기서 md5로 가고 싶을 수도 있습니다)을 데이터베이스에 저장해야합니다.

    자주 사용자 테이블에 추가 열을 추가하면됩니다. 그러나 이것은 또한 암호가 재설정되거나 사용자가 활성화되면 데이터베이스에서 키를 제거하여 대부분의 행이 널 값을 가지게되어 몇 가지 다른 문제를 유발한다는 점에서 몇 가지 문제가 있습니다 .

    이것이 본질적으로 귀결 : 고유를 위해 더 - 사용자 소금 ( 아마도 세계, 비밀 소금)을 사용하여

    • 해시 사용자의 암호를.
    • 무작위로 물건을 원한다면 타임 스탬프, mt_rand() 또는 random.org와 같은 임의 또는 의사 랜덤 소스를 해싱하여 키를 생성하십시오.
    • 는 글로벌 소금 또는 사용자가 암호 재설정 키, 활성 키 등

    내가 더으로 생각하지하시기 바랍니다 포함에 대한 액세스 권한을 얻는 것을 해싱에 대한 사용자 고유 소금을 사용하지 마십시오 보안 전문가를 의미하며, 나는 많은 것들을 잊었을 것입니다. 그리고 저는 아주 나쁜 습관들을 언급했을 것입니다. 내 5 센트 ;-)

  • 1

    인터넷에 방법을 게시 할 때까지 충분히 안전했습니다. 이것은 당신이 모호함에 의한 보안에 의존했기 때문입니다. 이것은 좋은 생각이 아닙니다.

    여러분에게만 알려진 비밀 키가 포함 된 일종의 키순 해시 함수 또는 MAC를 이상적으로 사용해야합니다.

    +2

    분명히 'x'es는 코드에서 실제로'x'es가 아닙니다. – Mala

    +0

    이 경우, 키순 해시 함수를 생성 했으므로 이제 가야합니다. 나는 아마 ...)) –

    +0

    ;)을 미안하다 내가 그것을 지정했다고 생각 - 분명히 내가 명시 적으로 그 곳을 말한 비트를 편집 ... 어떤 경우에는 내가 테이블 구조/사용하는 경우 궁금하네요 모든 코드에 대한 하나의 테이블이 적절합니다 – Mala

    0

    왜 코드 필드에 고유 색인을 만들지 않습니까? 그럼 절대로 절대로 충돌하지 않을거야? 사용자 입력에서 해시를 생성하고 데이터베이스 해시에 일치 할 필요가없는 경우도

    , (이메일 확인, 비밀번호 등을 재설정) - 당신이 md5('xxx'.$username.'xxx'.time().'xxx'.rand())

    +0

    그럼 나는 데이터베이스를 사용하지 않고 그것을 검사 할 수 없을 것입니다 - 그 기능의 전체 요점은 그들을 사용하지 않도록했다.어쨌든 데이터베이스를 사용할 예정이라면 전체 문자열을 완전히 무작위로 만들 수 있습니다. – Mala

    2

    같은 해시 본체에 임의의 문자열을 추가 할 수 있습니다 왜 사용자의 데이터를 인증 키의 기초로 사용합니까?

    비활성화 된 데이터를 데이터베이스에 저장한다고 가정하기 만하면 무작위 키 (아마도 추가 조작이 포함 된 md5'ed uniqid) 인 추가 레코드를 추가 한 다음 그 레코드를 확인하는 것이 좋습니다.

    +0

    원래 데이터베이스를 사용하지 않으려 고했기 때문에 사용자 데이터를 사용합니다. – Mala

    +1

    솔직히 말해서, 도움이되지만 데이터베이스가 갈 길이라고 생각하면, 그렇지 않으면 꽤 제한된 정적 데이터 풀을 해싱/조작하게 될 것입니다. –

    0

    사용자에게 사용자 이름 을 입력하도록 요청하면 충돌로 인한 문제를 해결할 수 있습니다.이메일을 통해 얻을 수있는 키를 요청하면서 보안 측면에서 어떤 것도 잃지는 않지만 다른 사용자의 비밀번호를 재설정 할 수 없게됩니다.

    +1

    전자 메일의 링크를 클릭하는 것이 이상적입니다. 나는 이것을 horrendously long = P가되기 싫어. – Mala