본문 바로가기

웹/school(MEAN)

Authenticating users,managing sessions, and securing APIs [1]

앵귤러에서 인증을 관리해 봅시다.

 

전통적인 서버 기반에 애플리케이션 인증을 넣기

옛날에는 서버에 정보를 넘기고 서버는 데이터를 보고 로그인을 시켜줍니다.

 

서버는 세션 정보를 사용하여 사용자의 브라우저에 쿠키를 설정하거나 설정하지 않을 수 있다

세션이 연결된 상태에서

서버는 세션의 유효성을 검사합니다.

브라우저가 새로운 페이지에 접근하려면 쿠키를 보냅니다.

 

서버는 이 브라우저가 누구인지 압니다 "지난번에 접근했던 사람"

인증이 유효하면 서버는

페이지를 브라우저에게 보냅니다.

 

세션은 브라우저를 빠져나갈 때 까지를 의미 합니다.

 

사용자가 db에 접근해서 저장하고 싶은 때 

유효한 세션을 통해서 저장할 수 있습니다.

 

 

MEAN 스택에서의 전통적인 방법 접근

MEAN 스택에서는 어울리지 않습니다.

 

node.js는 사용자의 세션을 연결시켜주지 않습니다.

 

데이터 서비스 api를 사용하는 spa에 인증을 추가하는 방법을 해봅시다.

 

 

 

그러나 MEAN 스택의 인증에는 두 가지 문제가 있습니다

  • Express/Node 에는 사용자 세션의 개념이 없으므로 API 가 상태를 저장하지 않는다
  • SPA 로직이 이미 브라우저에 다운로드되어 있으므로 제공된 코드를 제한할 수가 없다

 

세션을 유지하기 위해 브라우저에 사용자 데이터를 안전하게 보관하는 가장 좋은 방법 은 JWT(JSON Web Token)를 사용하는 것이다

 

 

로그인 과정을 살펴봅시다

브라우저는 서버로 데이터를 보냅니다.

 

서버는 db에 유효성을 검사하고

json web token을 생성합니다. 그 후 브라우저에게 토큰을 줍니다.

 

사용자의 세션 데이터를 브라우저에게 전달해 브라우저에 저장이 됩니다.

 

사용자가 세션에 있는 동안

애플리케이션에서는 jwt를 디코더를 해서 사용자의 접근 권한을 제어합니다.

 

이것이 전통적인 제어 방식과 차이가 있는 것입니다.

 

모든 내용은 브라우저에서 처리가 됩니다.

 

누가 호출했는지 알 수 없습니다.

api를 호출할 때 브라우저에서는 데이터와 함께 토큰(JWT)을 서버에 보냅니다.

서버는 디코딩을 해서 자격이 있는지 확인합니다.

 

 

MongoDB로 user와 password를 저장해 봅시다.

 

단방향 암호화란?

 

암호화된 값과 일치하는지 확인해야 합니다.

 

 

Salt 개념

임의의 문자열을 결합해서 유저 패스워드에 붙입니다.

결과로 hash가 나옵니다.

 

 

먼저 스키마를 만듭시다

user 스키마에는 무엇을 둘까요?

이름, password, email이 필요합니다.

 

salt와 hash를 설정해야 합니다.

 

mongoose를 사용하면 모델 메서드로 노출되는 스키마에 methods를 추가할 수 있습니다.

setPassword()는 hash라는 unique 한 키를 만들어야 합니다.

 

스키마 정의된 후, 모델이 컴파일되기 전에 추가해야 합니다.

현재 객체의 salt와 hash에 넣습니다.

 

db에 저장하기 전에 salt과 hash라는 것을 생성해야 하는데 

crypto라는 것으로 암호화를 할 수 있습니다.

 

cypto 사용하기

 

 

setPassword 메서드를 만들어 봅시다.

사용자로부터 password를 받아들이고 

crypto의 메서드로 salt와 hash값을 받아들입니다.

 

password로 인증을 해야 합니다.

다른 페이지로 갈 수 있는지 없는지를 결정해줘야 합니다.

 

setPassword로 암호화했습니다.

사용자가 새롭게 로그인하려고 합니다.

 

그것을 검증하는 메서드인 validPassword()를 만듭시다.

 

들어온 password를 똑같은 hash값으로 만들어서 저장된 hash값과 비교합니다.

 

 

JWT를 생성해봅시다.

서버의 api와 브라우저의 spa 간에 데이터를 전달하는 데 사용됩니다.

사용자를 인증하는 데 사용됩니다.

JWT 자세히 보기

처음 헤더와 페이로드는 암호화가 되지 않고 인코딩 됩니다.

 

secret은 서버에만 존재해야 합니다.

 

이런 과정을 쉽게 처리할 라이브러리가 있습니다.

 

 

generateJwt메서드에 페이로드, secret값을 줘야 합니다.

토큰의 만료 날짜도 설정해서 보내야 합니다.

 

sign() 메서드를 호출해서 

페이로드 -> json 객체

secret -> 문자열

로 만듭니다.

완료 날짜를 설정하고요

sign()메소드를 이용해서

사용자의 id, email, name을 줍니다.

 

secret이 보이지 않아야 합니다.

 

secret 하게 저장하기 위해 환경변수로 지정합니다.

 

환경 변수를 설정하려면 dotenv라는 npm모듈이 필요합니다.

 

Heroku도 설정을 해줘야 합니다.

 

 

728x90