Day56,57,58 S3U7 Backend 인증 / 보안

Janny·2022년 11월 13일
0

Cookie / Session

서버에서 클라이언트에 영속성있는 데이터를 저장하는 방법
서버가 원한다면 서버는 클라이언트의 쿠키를 이용하여 데이터를 가져올 수 있다.

서버가 클라이언트에 특정한 데이터를 저장할 수 있다.

데이터를 저장한 이후 특정 조건들이 만족되어야 다시 가져올 수 있다.

'Set-Cookie':[
            'cookie=yummy', 
            'Secure=Secure; Secure',
            'HttpOnly=HttpOnly; HttpOnly',
            'Path=Path; Path=/cookie',
            'Doamin=Domain; Domain=codestates.com'
        ]
  1. Domain
    www.google.com과 같은 서버에 접속할 수 있는 이름
    포트 및 서브 도메인 정보, 세부 경로를 포함하지 않는다.
    (http://www.localhost.com:3000/users/login 라면 도메인은localhost.com)

  2. Path
    세부 경로로써 서버가 라우팅할 때 사용하는 경로를 의미
    명시하지 않으면 기본적으로 /으로 설정
    설정된 경로를 포함하는 하위 경로로 요청을 하더라도 쿠키를 서버에 전송할 수 있다.
    (http://www.localhost.com:3000/users/login 라면 path는/users/login)

  3. MaxAge or Expires
    쿠키가 유효한 기간을 정하는 옵션
    MaxAge는 쿠키가 유효한 시간을 초 단위로 설정하는 옵션
    Expires은 MaxAge와 비슷하지만 언제까지 쿠키가 유효한지 심판의 날을 지정 (클라이언트의 시간을 기준으로 함)

세션쿠키 : MaxAge 또는 Expires 옵션이 없는 쿠키. 브라우저를 종료하면 쿠키가 삭제 된다.
영속성쿠키 : 브라우저의 종료 여부와 상관없이 MaxAge 또는 Expires에 지정된 유효시간만큼 사용가능한 쿠키

  1. Secure
    사용하는 프로토콜에 따른 쿠키의 전송여부를 결정하는 옵션
    Secure 옵션이 true로 설정된 경우 HTTPS를 이용하는 경우에만 쿠키를 전송할 수 있다.

  2. HttpOnly
    자바스크립트에서 브라우저의 쿠키에 접근 여부를 결정
    HttpOnly 옵션이 true로 설정된 경우, 자바스크립트로 쿠키에 접근이 불가하다.
    명시하지 않을 경우 false로 지정 (자바스크립트에서 쿠키 접근 가능 ➡️ XSS 공격에 취약)

  3. SameSite
    Cross-Origin 요청을 받은 경우, 요청에서 사용한 메소드와 해당 옵션(e.g. GET, POST, PUT, PATCH …)의 조합을 기준으로 서버의 쿠키 전송 여부를 결정
    - Lax: Cross-Origin 요청이라면 GET 메소드에 대해서만 쿠키를 전송할 수 있다.
    - Strict: 단어 그대로 가장 엄격한 옵션으로, Cross-Origin이 아닌 same-site (요청을 보낸 Origin과 서버의 도메인, 프로토콜, 포트가 같은 경우) 인 경우에만 쿠키를 전송 할 수 있다.
    - None: Cross-Origin에 대해 가장 관대한 옵션으로 항상 쿠키를 보내줄 수 있다. 다만 쿠키 옵션 중 Secure 옵션이 필요하다.

쿠키를 이용한 상태 유지

서버는 클라이언트의 인증정보를 담은 쿠키를 전송하고, 클라이언트는 전달받은 쿠키를 서버에 요청과 같이 전송하여 Stateless한 인터넷 연결을 Stateful하게 유지할 수 있다.
하지만 기본적으로 쿠키는 오랜 시간 동안 유지될 수 있고, HttpOnly 옵션을 사용하지 않았다면 자바스크립트를 이용해서 쿠키에 접근할 수 있기 때문에 쿠키에 민감한 정보를 담는 것은 위험하다.

Axios

fetch API와 비슷한 역할을 하는 라이브러리
브라우저, Node.js를 위한 Promise API를 활용하는 HTTP 비동기 통신 라이브러리

AxiosFetch API
서드파티 라이브러리로 설치가 필요빌트인 API라 별도의 설치 필요없음
자동으로 JSON데이터 형식으로 변환.json()메서드를 사용해야 함

설치방법

npm install axios

GET 요청

axios.get("url"[,config])

관련공식문서

Session

로그인

서버가 "유저가 인증에 성공했음" 을 알고 있다면 매번 로그인 할 필요가 없다.
서버: 사용자가 인증에 성공했음을 알고 있어야 함
클라이언트: 인증 성공을 증명할 수단을 갖고 있어야 함
사용자가 인증에 성공한 상태를 세션이라고 부른다.
서버는 일종의 저장소에 세션을 저장한다.
세션이 만들어지면 각 세션을 구분할 수 있는 세션 아이디를 만드는 데, 클라이언트의 세션 성공을 증명할 수단으로써 세션 아이디를 전달한다.
이 때, 웹사이트에서 로그인을 유지하기 위한 수단으로 쿠키를 사용한다.
쿠키에는 서버에서 발급한 세션 아이디를 저장한다.
쿠키에 세션 아이디 정보가 없는 경우 서버에서는 해당 요청이 인증 되지 않았음을 알려준다.

로그아웃

서버: 세션 정보를 삭제해야 한다.
클라이언트: 쿠키를 갱신해야 한다.
서버는 클라이언트의 쿠키를 임의로 삭제할 수 없다.
대신 set-cookie로 클라이언트에게 쿠키를 전송할 때 세션 아이디의 키 값을 무효한 값으로 갱신할 수 있다.

express-session

Node.js에 있는 이런 세션을 대신 관리해 주는 express-session 이라는 모듈
세션을 위한 미들웨어로, express 서버에서 쉽게 세션을 위한 공간을 다룰 수 있도록 해준다.

const express = require('express');
const session = require('express-session');

const app = express();

app.use(
  session({
    secret: '@codestates',
    resave: false,
    saveUninitialized: true,
    cookie: {
      domain: 'localhost',
      path: '/',
      maxAge: 24 * 6 * 60 * 10000,
      sameSite: 'none',
      httpOnly: false,
      secure: true,
    },
  })
);

쿠키 옵션과 유사해 보이지만 secret옵션의 비밀키를 이용해 암호화해서 세션 id 라는 것을 생성한다. 이를 클라이언트에게 쿠키로 전송한다.

관련 내용 첨부

Token

Hashing

가장 많이 쓰이는 암호화 방식 중 하나
암호화만 가능하다

  • 항상 같은 길이의 문자열을 리턴
  • 서로 다른 문자열에 동일한 해시 함수를 사용하면 반드시 다른 결과값이 나온다.
  • 동일한 문자열에 동일한 해시 함수를 사용하면 항상 같은 결과값이 나온다.

레인보우 테이블 / 솔트(Salt)

레인보우 테이블: 해시 함수를 거치기 이전의 값을 알아낼 수 있도록 기록해놓은 표 (유출 시 해싱 이전의 값을 알아낼 수 있으므로 보안상 위협이 될 수 있다.)
솔트: 소금을 치듯 해싱 이전 값에 임의의 값을 더해 데이터가 유출되더라도 해싱 이전의 값을 알아내기 더욱 어렵게 만드는 방법

해싱의 목적

데이터 그 자체를 사용하는 것이 아니라, 동일 값의 데이터를 사용하고 있는지 여부만 확인하는 것이 목적
(ex. 사이트 관리자의 사용자 비밀번호 일치 여부 ➡️ 비밀번호 값 자체를 알 필요는 없음)
민감한 데이터를 다루어야 하는 상황에서 유출 위험성을 줄이고, 데이터 유효성 검증을 위한 단방향 암호화 방식이다.

Token

토큰 기반 인증 중 가장 대표적인 JWT(JSON Web Token)
토큰은 유저 정보를 암호화하기 때문에 클라이언트에 담을 수 있다. ( ↔️ 민감한 정보는 클라이언트에 담으면 안된다.)

JWT의 종류

  1. 엑세스 토큰 (Access Token)
    보호된 정보들에 접근할 수 있는 권한 부여에 사용된다.
    짧은 유효기간 (토큰을 탈취하더라도 오랫동안 사용할 수 없게 함)

  2. 리프레시 토큰 (Refresh Token)
    액세스 토큰이 만료되면 리프레시 토큰을 사용해서 새로운 액세스 토큰을 발급 받는다.

JWT의 구조

  1. Header
    어떤 종류의 토큰인지, 어떤 알고리즘으로 시그니처를 sign(암호화) 할지가 적혀있다.
{
"alg": "HS256",
"typ": "JWT"
}

이 JSON 객체를 base64 방식으로 인코딩하면 완성이다.

  1. Payload
    단어 그대로 서버에서 활용할 수 있는 유저의 정보가 담겨있다. 어떤 정보에 접근 가능한지에 대한 권한 또는 유저의 이름과 같은 개인정보를 담을 수 있다. 디코딩이 쉬운 base64 방식으로 인코딩되기때문에 민감한 정보는 담지 않는 것이 좋다.
{
	"sub": "someInformation",
    "name": "philip",
    "iat": 151623391
}

이 JSON 객체를 base64 방식으로 인코딩하면 완성이다.

  1. Signature
    인코딩된 첫번째, 두번째 부분을 서버의 비밀 키(암호화에 추가할 salt)와 헤더에서 지정한 알고리즘을 사용하여 해싱하는 것.
HMACSHA256(base64UrlEncode(header) + '.' + base64UrlEncode(payload), secret);

토큰기반 인증절차

토큰기반 인증의 장점

  1. 무상태성 & 확장성 (Statelessness & Scalability)
    서버에 클라이언트의 정보를 저장할 필요가 없다.
    클라이언트는 새로운 요청을 보낼 때 마다 토큰을 헤더에 포함시키면 된다.
    서버를 여러개 가지고 있는 서비스라면 같은 토큰으로 여러 서버에 인증일 가능하기 때문에 더 유용하다.

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

  3. 어디서나 생성 가능하다.
    토큰을 확인하는 서버가 직접 토큰을 만들 필요가 없으므로, 토큰 생성용 서버를 만들거나 다른 회사에 작업을 맡기는 등의 활용이 가능하다.

  4. 권한부여에 용이하다.
    토큰의 내용물(payload)안에 어떤 정보에 접근 가능한지 정할 수 있다.
    (ex. 특정 어플에서 사진과 연락처 사용권한만 부여)

OAuth

(OAuth2.0) 웹이나 앱에서 흔히 쓰는 소셜 로그인 인증방식의 바탕 기술
인증을 중개해주는 매커니즘
보안된 리소스에 액세스하기 위해 클라이언트에게 권한을 제공하는 프로세스를 단순화 하는 프로토콜
이미 사용자 정보를 가지고 있는 웹 서비스에서 사용자의 인증을 대신해주고, 접근 권한에 대한 토큰을 발급한 후 이를 이용해 서버에서 인증이 가능해지는 것

장점: 이용자들은 이미 가입된 계정을 이용해 빠르게 서비스에 가입할 수 있다. 서비스를 구현하는 개발자도 회원관리를 신경쓰지 않아도 된다. 검증되지 않은 앱에서 OAuth를 사용하여 로그인한다면 민감한 정보가 앱에 노출될 일이 없고, 인증권한에 대한 허가를 미리 유저에게 구해야 하기 때문에 보안상의 이점도 있다.

OAuth에서 알아야 할 용어

Resource Owner: 사용자이며 정보 제공자
Client: Resource Owner를 대신하여 보호된 리소스에 액세스하는 애플리케이션
Local Server: Client의 요청을 수락하고 응답할 수 있는 서버
Resource Server: 사용자의 정보를 저장하고 있는 서버
Authorization Server: 인증을 담당하고 있는 서버, Access Token을 발급하는 인증 서버
Authorization Grant: Client가 Access Token을 얻는 방법

  • Authorization Code Grant Type
  • Refresh Token Grant Type
    Authorization Code: Authorization Grant의 한 타입으로 Access Token을 발급받기 위한 Code를 의미
    Access Token: 보호된 리소스에 액세스하는 데 사용되는 인증 토큰, 이 Access Token으로 이제 Resource Server에 접근할 수 있다.
    Refresh Token: 발급받은 Access Token이 만료될 시 Refresh Token을 통해 새로운 Access Token을 받급받을 수 있다.

OAuth 인증 흐름

Authorization Code Grant Type
Authorization Code를 받아 Authorization Code를 통해 Access Token을 받는 방식
Access Token이 사용자나 브라우저에 표시되지 않는다 (누출 위험 낮음)
Refresh Token Grant Type
Authorization Code Grant Type으로 Access Token을 발급받은 후 Access Token이 만료된 경우 Refresh Token을 활용해 새로운 Access Token으로 교환하는 데 사용.
사용자와의 추가 상호 작용 없이 계속 유효한 액세스 토큰을 가질 수 있다.

profile
🐣병아리 개발자의 기록을 위한 공간

0개의 댓글