Session.15 Authentication/Authorization

*🔐Study Keyword :

🔑인증/인가가 무엇이며 어떤 차이가 있는지
🔑JWT에 대해서 이해하고 프론트에서 토큰을 어떻게 관리해야할지에 대해서

- 위벅스 로그인 페이지에 대한 인증/ 인가 실습

  • 현재 리액트로 만든 로그인 페이지에 나의 이메일과 패스워드가 있다.
  • 아이디와 비빌번호를 state값에 저장하고 서버로 아이디와 비밀번호 자체를 보내야한다.
  • 버튼 클릭 시 혹은 엔터를 누르면 엔터를 누르면 서버와 통신을 한다는 의미로 통신시에 서버에서 로그인(혹은 회원가입)에 성공과 실패에 대한 응답을 보낸다. 결국 로그인과 회원가입 모두 다른 함수를 호출 함으로서 두 가지 모두를 구현할 수 있다.

  • 클릭 시 발생 할 함수 내부에 fetch 함수를 이용해 로그인, 회원가입 api를 받아서 Request 요청 메서드를 POST로 작성해준다.
  • 키와 값의 형태로 헤더에는 요청의 메타데이터를 담아주고 바디에 메타정보의 실제 내용인 유저의 계정 정보, 아이디와 비밀번호를 적는다.
  • 벡앤드에선 프론트에서 보낸 POST Request를 받은 후 아이디와 비밀번호에 json 형태로 보낸다

  • 이후 서버에서 인증, 인가를 위한 JWT, 웹토큰을 만들기 위한 과정을 거친 뒤 요청에 대하여 승인 혹은 거절 중 하나를 응답한다.
  • 가령 이미 존재하는 ID 등의 이유로 회원가입에 실패해 응답이 거절을 보내면 프론트에서는 사용자에게 잘못된 입력이라는 것을 알려준다.
  • 혹은 로그인에 성공하면 메인페이지로 이동, 로그인 가입 성공 에 대한 모달창 띄우기 등에 다음 로직을 진행한다.

- fetch 함수 활용 법

  • fatch 함수의 두번 째인자로 키가 3개, 1> method, 2>headers, 3> body가 들어간다.
  • 그에 대한 값으로 1> method는 POST로 2> headers에는 통신형태를 JSON 파일로 하겠음을 의미하는 application/json을 명시해주고
    3> body에는 통신할 때 JSON 형태의 객체를 문자열 형태로 변환하여 통신하기 위한 메서드로 JSON.stringfy 메서드의 내부에 객체 형태로 email과 password를 담아서 요청을 보내준다.
    (💡주의주의💡, 이때 해당 키의 값, email과 password는 서버에서 명시해준 변수명을 사용해야한다!!)
  • 이후 then 메서드로 요청에대한 응답을 받으면 json() 메서드를 사용하여 다시 json 형태로 받아내고 다시 then 메서드로 응답에 대한 결과 값을 로그로 찍으면 된다.
  • 같은 페이지로 회원가입 성공 후 회원가입을 했던 이메일 아이디로 로그인 하여 성공 후 서버로부터 로그인에 대한 JWT을 받으면 미션 완료!
  • 이 fetch 함수는 로그인 버튼 혹은 회원가입 버튼을 클릭을 했을 때처럼 이벤트가 발생했을 때 사용자가 작성한 로그인과 이메인에 대한 값을 state에 담아서 서버에 로그인 혹은 회원가입에 대한 api를 받아서 실행할 수 있도록 구현 해준다!

1. 인증(Authentication)

-WHAT IS❓

  • Authentication이란 유저의 identification을 확인하는 절차이다.
    -즉, 유저의 아이디와 비번을 확인하는 절차인증을 하기 위해서는 유저의 아이디와 비번을 생성할 수 있는 기능이 필수적이다.

1_1. 로그인 절차

  1. 유저 아이디와 비번 생성한다.
  2. 유저 비밀번호를 암호화 해서 DB에 저장한다. (=회원가입)
  3. 유저가 로그인하면 아이디와 비밀번호 입력한다.
  4. 유저가 입력한 비밀번호를 암호화 한 후 DB에 저정된 암호화된 유저 비밀번호와 비교한다.
  5. 일치하면 로그인 성공 !
  6. 로그인에 성공하면 access token을 클라이언트에게 전송한다.
  7. 유저는 로그인 성공하면 이후엔 access token을 첨부해서 request를 서버에 전송함으로서 매번 로그인을 하지 않아도 된다.
  • 이처럼 유저가 서버에 로그인 절차를 거쳐서 로그인을 해달라는 요청을 보내면 인증의 과정을 거쳐 이 사용자의 식별자를 확인하는 작업이 필요하다.

1_2. 이전 세대와 현재의 인증/인가 처리 방식

  • 이전 세대의 인증/인가 방식-세션 아이디를 쿠키형태로 전송을 받아 브라우저에 매번 저장하여 사용했다.
    -한 곳의 서버에만 저장되어 다른 곳에 쓸 수 없다는 치명적인 단점이 존재한다.
  • 현재의 인증/인가 처리 방식

    -로그인을 한 번만 하면 페이지 내의 다른 서비스를 모두 이용할 수 가 있다.
  • 따라서 이전처럼 세션에 저장하지 않고 유저 개인이 토큰을 가지고 있고 이를 통해 매번 자신의 식별을 증명하는 방식으로 진행된다.
  • 유저가 로그인에 성공하면 access token이란 암호화된 유저 정보를 첨부해서 request를 서버로 보낸다.
  • 이때 ccess token에 대한 시크릿 키를 서버가 가지면 각가의 서버(admin, user server)들이 시크릿 키를 공유하여 사용할 수 있다.
<script>
// 유저 로그인
POST /auth HTTP/1.1
Host: localhost:5000
Content-Type: application/json
{
    "username": "joe",
    "password": "pass"
}
// access token
HTTP/1.1 200 OK
Content-Type: application/json
{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGl0eSI6MSwiaWF0IjoxNDQ0OTE3NjQwLCJuYmYiOjE0NDQ5MTc2NDAsImV4cCI6MTQ0NDkxNzk0MH0.KPmI6WSjRjlpzecPvs3q_T3cJQvAgJvaQAPtk1abC_E"
}
</script>

JWT(JSON Web Tokens)

  • 매번 클라이언트와 서버에 통신이 이뤄질 때 서버에선 유저가 로그인했다는 사실을 알려줘야한다.
  • 위 이미지처럼 "나 로그인했어"와 메세지가 HTTP 통신상에 발급 받는 토큰으로 즉, 유저가 로그인을 하기 위해선 토큰이 필수적이다.
  • 서버에서 access token을 복호화하여 해당 로그인을 한 유저에 대한 정보를 얻는데 access token을 복호화 하면 다음과 같은 정보를 얻을 수 있다.
<script>
// access token
HTTP/1.1 200 OK
Content-Type: application/json
{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGl0eSI6MSwiaWF0IjoxNDQ0OTE3NjQwLCJuYmYiOjE0NDQ5MTc2NDAsImV4cCI6MTQ0NDkxNzk0MH0.KPmI6WSjRjlpzecPvs3q_T3cJQvAgJvaQAPtk1abC_E"
// 복호화 한 유저 정보![](https://media.vlpt.us/images/minj9_6/post/7f371634-2527-4dcb-aa82-71a493d32273/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-09-11%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%202.33.35.png)
}
{
user_id : 1 
}
</script>
  • 이렇게 복호화해서 얻은 유저 아이디를 통해 해당 유저가 누구인지(식별)를 서버가 알고 이를 통해 해당 유저가 매번 로그인을 하지 않아도 되게된다.
  • access token을 생성하는 방법에는 여러가지가 있는데 가장 보편적으로 쓰는 기술이 바로 JWT(JSON Web Tokens)이다.

-WHAT IS❓

  • JWT(JSON Web Tokens)유저 정보를 담은 JSON 데이터를 암호화하여 클라이언트와 서버간에 주고 받는 토큰을 의미한다
  • 빨간 글자가 1> header 부분, 주황색 글자는 2> body로 ID 3번인 유저, 토큰의 만료 기간 같은 정보를 넣고 마지막 노랑 글자는 3> signature로 암호화 되어있어 특정 서버에 key가 있어야만 이를 복호화하여 사용가능하다.

1> header에는 암호화 되어있지 않고 인코딩(형태를 바꾸어서)한 토큰의 타입과 해시알고리즘 정보가 들어가 있다.

2> body에는 토큰 안에 뭐가 들어있는지, 즉 사용자에 대한 정보가 문자열의 형태로 들어가있어 서버에서 토큰의 body에서 사용자에 대한 정보를 받아온다.

  • body 역시 암호화 되지 않고 인코딩만 되어있다.
  • 💡주의주의💡, 민감한 정보는 body에 저장하지 않고 서버만 알 수 있는 번호만을 넣는다.
  • 서버의 데이터 베이스에서만 관리할 수 있는 유저에 대한 정보를 넣는다.
    즉, EMAIL, 주민번호, 비밀번호 같은 건 넣을 필요없다는 것!

3> signature은 엄격한 내용들이 들어가며 토큰을 가지고 결제를 할 수 있는 등의 것들을 진행한다.

  • 해당 토큰의 signature 부분은 특정 서버에서만 동작하며 해당 토큰이 유저 본인이 발행한 것임을 증명하는 부분을 넣어준다
  • 이때 특정 문자열을 넣어서 특정 문자열을 인증해야만 복호화가 가능하도록하고 보통 회사의 시그니처를 넣곤한다.

JWT 티켓을 받은 후 클라이언 측의 과정

  • 유저가 로그인 시 로그인 API를 거쳐 로그인을 성공하면 서버에서 JWT 티켓을 생성하여 FRONT, 클라이언트 측으로 건네준다.
  • 건네준 토큰은 네트워크를 통해 프론트엔드 개발자가 토큰 티켓을 받게되고 이를 브라우저에서 저장한다.
  • 유저의 브라우저에 이 토큰을 어딘가에 저장하고 있다가 페이지간 이동이 있을때 마다, 혹은 브라우저를 끄고 켤때마다 access token을 주고 받아서 사용자 인증을 진행한다.

참고) 전달받은 access token을 저장한다는 어딘가는 어딘가!?

  1. 해당 도메인에 영구 저장하고 싶을 때는 Local Storage에 저장
  2. 해당 도메인의, 한 가지 세션에만 저장할 땐 Session Storage에 저장, 단 브라우저 창을 닫으면 data가 없어진다.
  3. 해당 도메인에 날짜를 설정하고 설정한 날짜까지만 저장하고 싶을 땐 Cookie에 저장한다.

*💡conclusion

  • 인증/인가 그리고 JWT는 면접의 질문의 맛집이라하시니 꼭 이 플로우를 정리하자!
  • 인증의 구조에 대해서
  • JWT 사용함으로서 어떤 장점이 생겼는지
  • 토큰을 발행하는 것을 어떻게 할지에 대해서는 벡앤드를 하면서
  • 백엔드에서 발급한 토큰, JWT를 클라이언트가 어떻게 받을 수 있는지 또 어떻게 관리 해야하는지에 대해서까지 스스로 묻고 대답해보기

#📑Study Source

  • 소헌님의 다음 주 본격 node.js 섹션 전 알아야하는 필수 개념들이 쏙쏙들어간 강의 중:)

좋은 웹페이지 즐겨찾기