Search
▪️

Advanced Authentication

Implementing the Token Logic

Resetting Password와 같이 만료 기간을 둔 링크를 통해서 작업하는 것들은 Unique한 Token이 필요하다.
이 때 사용하는 Token들 역시 Session처럼 데이터베이스에 저장하게 된다.
사용자가 Token이 포함된 링크를 클릭 시, Reset Password를 보낸 것이 Server임을 입증할 수 있게 되고 이에 따라 Resetting Password를 할 수 있다.
Resetting Password를 수행할 시, 아무런 Security Mechanism이 없으므로, 받았던 Token을 돌려보냄으로써 위조되지 않은 Request임을 알린다.
Token을 생성하는 것은 Node.js에 내포된 crypto라는 Libarary를 통해서 생성할 수 있다.
crypto를 통해서 Unique Random Values를 생성할 수 있다.
우선 Random Value를 만들기 위해서 crypto.randomBytes로 생성을 하며, 인자로 Random Value의 길이를 지정한다. 길이에 대한 인자 다음으로는, Random Bytes들이 생성된 후 호출될 Callback Function을 받는다. Callback Function의 인자는 error와 buffer를 받는다.
생성된 Buffer를 통해 Callback Function 내에서 Token을 생성하게 된다. buffer.toString()이 Token이다.
Token 값을 데이터베이스에 저장할 때, Token값과 Expiration을 같이 저장하도록 한다.
Expiration을 사용할 때는, Date 타입으로 사용하게 되며, 해당 타입에 대한 연산을 수행할 때는 + -와 같은 연산이 가능하다. 단, Millisecond 단위임을 명심해야 한다.
두 값을 데이터 베이스에 저장하고 난 후, Token값을 내포하고 있는 링크를 이메일로 전송한다.

Creating the Reset Password Form

이메일의 링크를 통해서 Token 값을 받았으므로, 해당 링크를 열었을 때 Token 값이 위조된 것인지 Token값을 갖고 있는 사용자를 탐색하여 검증한다. 만일 위조되지 않은 Token이라면 Password를 Resetting하는 Page를 Render한다. (즉, 페이지를 POST할 때 Token 검증을 하는 것 뿐만 아니라, 링크를 열어서 GET할 때 Token값에 대한 검증을 치룬다.)
여기서 중요한 점은 Token의 위조 및 변조를 검증하기 위해서, Token 값이 매칭되는 사용자를 찾을 때 단순히 Token의 값으로만 비교하는 것이 아닌 Expiration도 같이 검증에 포함시켜야 한다.
Expiration의 경우, 특별한 연산이 필요하다. 단순히 이제처럼 값 Matching으로 찾는 것이 아니라, 현재 시간이 Expiration 값보다 작아야 하는 대소 비교가 필요하다. 이 findOne() Method에서 {}와 같은 Curly Braces 내에서 쓰이는 Special Operator를 통해서 가능하다. $gt는 Greater Than을 의미한다.

Adding Logic to Update the Password

Resetting Password를 POST할 때 역시, Token 값에 대한 검증을 한다.
사용자를 찾을 때는 사용자의 ID, Token값, Token의 Expiration을 통해서 사용자를 찾는다.
사용자의 비밀번호를 수정하고 나서는, 사용자가 갖고 있는 Token값과 Expiration을 null로 만들어줘야 한다. (null 말고 undefined로 할당해도 된다.)

Why We Need Authorization

Authorization은 로그인된 사용자의 권한은 제한하고, 역할에 따라서 수행 가능 범위를 나누는 것이다. (Restricting Permissions)
즉, 나라는 사용자가 생성한 항목을 최고 관리자 외에는 삭제할 수 없어야 하고, 그 반대도 마찬가지다.
항목 전체를 가져오는 것도, 삭제를 하는 것도, 수정을 하는 것도 모두 Authorization을 거쳐야 한다.