[Backend] 인증 / 보안220913~15 TIL

jisooo·2022년 9월 15일

이번주는 화요일부터 오늘까지 백엔드 인증/보안에 대해서 배웠다. 일단 정말 머리가 터질것같았다.. 백엔드 하시는 분들이 너무 존경스러웠고 처음으로 나랑 개발이 안맞나..? 하는 생각도 들었다 ㅠ 컨디션 최악인 상태에서 어려운걸 공부하려니 집중력도 많이 떨어지고 멘탈도 많이 붕괴됐던 3일이었지만, 컨디션 관리의 중요성을 느꼈다. 앞으로 더 중요한 프로젝트가 남아있기 때문에 그때까지 컨디션관리를 좀 신경써야겠다.

쿠키는 서버에서 클라이언트에 영속성있는 데이터를 저장하는 방법이다. 그러므로 서버가 원한다면 서버는 클라이언트의 쿠키를 이용하여 데이터를 가져올 수 있다. 데이터를 무조건 가져 올 수 있는 것은 아니고 특정 조건들이 만족되어야 다시 가져올 수 있다. 또 서버에 데이터를 보관하기 때문에 관리 비용이 많이 들 수있다. 데이터를 가져오기 위해서 아래와 같이 쿠키옵션을 설정하여 조건을 만족해야만 데이터를 가져올 수 있다.

'Set-Cookie':[
            'cookie=yummy', 
            'Secure=Secure; Secure',
            'HttpOnly=HttpOnly; HttpOnly',
            'Path=Path; Path=/cookie',
            'Doamin=Domain; Domain=codestates.com'
        ]

MaxAge or Expires:
쿠키가 유효한 기간을 정하는 옵션. 쿠키를 영원히 보관하게 되면 탈취당할 가능성이 있기 때문에 기간을 정하여 보관하는 것이 좋다.
Secure:
Secure 옵션이 true일 경우 HTTPS를 이용하는 경우에만 쿠키를 전송할 수 있다.
HttpOnly:
자바스크립트를 통한 브라우저의 쿠키에 접근 여부를 결정한다. true일 경우 자바스크립트로 쿠키에 접근이 불가능하기 때문에 보안상 이롭다.
SameSite
Cross-Origin 요청을 받은 경우 요청에서 사용한 메소드와 해당 옵션(e.g. GET, POST, PUT, PATCH …)의 조합을 기준으로 서버의 쿠키 전송 여부를 결정하게 됩니다. 사용 가능한 옵션은 다음과 같습니다.

Lax: Cross-Origin 요청이라면 GET 메소드에 대해서만 쿠키를 전송할 수 있다.
Strict: 단어 그대로 가장 엄격한 옵션으로, Cross-Origin이 아닌 same-site 인 경우에만 쿠키를 전송 할 수 있다.
None: Cross-Origin에 대해 가장 관대한 옵션으로 항상 쿠키를 보내줄 수 있다. 다만 쿠키 옵션 중 Secure 옵션이 필요함
이때 same-site는 요청을 보낸 Origin과 서버의 도메인, 프로토콜, 포트가 같은 경우를 말합니다. 이 중 하나라도 다르다면 Cross-Origin으로 구분된다.

서버에서 이러한 옵션들을 지정한 다음 서버에서 클라이언트로 쿠키를 처음 전송하게 된다면 헤더에 Set-Cookie라는 프로퍼티로 쿠키를 담아 전송하고,
이후 클라이언트에서 서버에게 쿠키를 전송해야 한다면 클라이언트는 헤더에 Cookie라는 프로퍼티에 쿠키를 담아 서버에 쿠키를 전송하게 된다.

Part 2. Session

세션은 사용자가 인증에 성공한 상태를 의미한다. 서버는 일종의 저장소에 세션을 저장하고, 주로 in-memory(자바스크립트 객체를 생각하면 됨), 또는 세션 스토어(redis 등과 같은 트랜잭션이 빠른 DB)에 저장한다.
세션이 만들어지면, 각 세션을 구분할 수 있는 세션 아이디도 만들어지는데(그림에서 3번), 보통 클라이언트에 세션 성공을 증명할 수단으로써 세션 아이디를 전달한다. (그림에서 4번)
이때 웹사이트에서 로그인을 유지하기 위한 수단으로 쿠키를 사용하고 쿠키에는 서버에서 발급한 세션 아이디를 저장한다.

쿠키를 통해 유효한 세션 아이디가 서버에 전달되고, (그림에서 5번) 세션 스토어에 해당 세션이 존재한다면 (그림에서 6번) 서버는 해당 요청에 접근 가능하다고 판단한다. (그림에서 7,8번)

하지만 쿠키에 세션 아이디 정보가 없는 경우, 서버는 해당 요청이 인증되지 않았음을 알려주게 된다.

Part 3. Token

Token은 쉽게 말해 통행증이다. Token은 세션과 달리 데이터를 클라이언트에 저장하게 해준다. 데이터를 클라이언트에 저장하게 되면 보안상 취약하지 않냐고 생각할 수 있지만, 데이터를 암호화와 복호화를 통해 처리하기 때문에 보안상 해롭지 않다.
토큰 기반 인증 중 가장 보편적인 것은 JWT이다.
JWT는 보통 두가지 종류의 토큰을 이용하여 인증을 구현하게 되는데,
Access TokenRefresh Token 이다.
Access Token은 보호된 정보들에 접근할 수 있는 권한부여에 사용한다. 클라이언트가 처음 인증을 받게 될 때(로그인 할 때)액세스 토큰과 리프레시 토큰 두가지를 다 받지만 실제로 권한을 얻는 데 사용하는 것은 액세스 토큰이다. 하지만 액세스 토큰의 경우 보안상 이유로 유효기간이 짧아 오랫동안 사용 할 수 없다. 이를 해결해 주는 것이 리프레시 토큰이다.
Refresh Token은 액세스 토큰의 유효기간이 만료되면 새로운 액세스 토큰을 받급 받도록 해주며 이때 유저는 다시 로그인 할 필요가 없다.
JWT의 구조
JWTHeader,Payload,Signature로 세 부분이 존재 한다.
1.Header
어떤 알고리즘으로 시그니처를 암호화 할지가 적혀 있다.

2.Payload
서버에서 활용 할 수 있는 유저의 정보가 담겨 있다. payload는 디코딩이 쉬운 base64 방식으로 인코딩 되기 때문에 너무 민감한 정보는 담지 않는게 좋다.

3.Signature
시그니처는 위에서 작성된 것들을 서버의 비밀 키와 헤더에서 지정한 알고리즘을 사용하여 암호화한다. 이로인해 비밀키를 갖고있지 않은경우 해독하는데 힘들게 된다.

토큰기반 인증의 장점
1. 무상태성&확장성 : 서버는 토큰이 해독되는지만 판단하기 때문에 서버에 데이터를 저장 할 필요가 없고, 클라이언트는 새로운 요청을 보낼 때 마다 토큰을 헤더에 포함시키면 되기 때문에 같은 토큰으로 여러 서버에서 인증이 가능해서 서버를 여러개 가진 경우 더더욱 좋다.

2.안전성: 암호화한 토큰을 사용하고 암호화 키를 노출 할 필요가 없어 안전하다.

3.어디서나 생성 가능 : 토큰을 확인하는 서버가 토큰을 만들지 않아도 되고, 다양한 활용이 가능하게 된다.

4.권한부여에 용이: 토큰의 페이로드안에 어떤 정보에 접근 가능한 지 정할 수 있다.

Part 4. OAuth

OAuth란?
전통적으로 직접 작성한 서버에서 인증을 처리해주는 것과는 다르게 인증을 중개해주는 메커니즘.
보안된 리소스에 액세스하기 위해 클라이언트에게 권한을 제공하는 프로세스를 단순화하는 프로토콜이다.

이미 사용자 정보를 가지고 있는 웹 서비스(Naver, Google, Facebook 등)에서 사용자의 인증을 대신해주고, 접근 권한에 대한 토큰 발급 후 이를 이용해 내 서버에서 인증이 가능해준다.

Resource Owner: 사용자이자 정보 제공자를 Resource Owner라고 한다.
Client: Resource Owner를 대신해 보호된 리소스에 액세스하는 애플리케이션
Local Server: Client의 요청을 수락하고 응답할 수 있는 서버
Resource Server: 사용자의 정보를 저장하고 있는 서버
Authorization Server: Access Token을 발급하는 인증 서버이다.
Authorization Grant: Client가 Access Token을 얻는 방법 다음과 같은 방법들이 주로 사용된다.
ex)Authorization Code Grant Type, Refresh Token Grant Type
Authorization Code: Authorization Grant의 한 타입으로 Access Token을 발급받기 위한 Code
Access Token: 보호된 리소스에 액세스하는 데 사용되는 인증 토큰. Resource Server에 접근가능
Refresh Token: Access Token이 만료시 Refresh Token을 통해 새로운 Access Token을 받급받을 수 있게 하는 토큰

0개의 댓글