관리 메뉴

Dev Blog

13. authentication 본문

BootCamp_Codestates/IM Tech Blog

13. authentication

Yongjae Kim 2021. 1. 20. 14:12
  • HTTPS
  • Hashing
  • CSRF
  • Cookie
  • Session
  • Token
  • OAuth

HTTPS 프로토콜

1) HTTPS 란?


Hyper Text Transfer Protocol Secure Socket layer
HTTP over SSL(TLS)
HTTP over Secure

HTTPS는 HTTP 요청을 *SSL 혹은 *TLS라는 알고리즘을 이용해, HTTP 통신을 하는 과정에서 내용을 암호화하여 데이터를 전송하는 방법. 인증에서 HTTPS 프로토콜을 사용해야만 하는 이유는 HTTP보다 상대적으로 안전한 방법이고, 인증서를 기반으로 데이터 제공자의 신원을 보장받을 수 있다.

*SSL (Secure Sockets Layer, SSL)
: SSL은 웹사이트와 브라우저(혹은, 두 서버) 사이에 전송된 데이터를 암호화하여 인터넷 연결을 보안을 유지하는 표준 기술입니다. 이는 해커가 개인 정보 및 금융 정보를 포함한 전송되는 모든 정보를 열람하거나 훔치는 것을 방지합니다.
*TLS(Transport Layer Security, TLS)
: TLS는 가장 최신 기술로 더 강력한 버전의 SSL입니다. 그러나 SSL이 더 일반적으로 사용되는 용어이기에, 여전히 보안 인증서는 SSL이라 불립니다.
*CA: SSL 인증서를 발급하는 신뢰할 수 있는 기관.

2) 데이터 제공자의 신원을 확인하고 보장받는 게 인증에서 중요한 이유

  • 클라이언트는 데이터 제공자가 제공해준 데이터를 사용할 수밖에 없습니다. 클라이언트는 서버에 데이터 요청을 하고 이후 받은 데이터를 이용해서 화면을 렌더링하는 등의 작업을 해야 합니다.
  • 그렇기 때문에 요청 및 응답을 중간에서 가로채는 중간자 공격에 취약합니다. '중간자 공격'은 클라이언트와 서버 사이에서 공격자가 서로의 요청, 응답의 데이터를 탈취 및 변조하여 다시 전송하는 공격입니다.

3) 암호화

HTTPS 프로토콜의 특징 중 하나는 암호화된 데이터를 주고받기 때문에, 중간에 인터넷 요청이 탈취되더라도 그 내용을 알아볼 수 없다는 것입니다. 공개 키 암호화 방식을 사용합니다.

before and after

4) 인증서(클라이언트가 확인하는 것)

브라우저가 응답과 함께 전달된 인증서 정보를 확인할 수 있습니다. 브라우저는 인증서에서 해당 인증서를 발급한 CA 정보를 확인하고 인증된 CA가 발급한 인증서가 아니라면 아래와 같이 화면에 경고창을 띄워 서버와 연결이 안전하지 않다는 화면을 보여줍니다.

- 데이터 제공자 신원 보장.
- 인증서의 내용에 서버의 도메인 관련 정보가 있어 데이터 제공자의 인증이 용이.
- 인증서의 domain 과 응답객체의 domain 일치여부 확인. 만약 해커가 제 3자 공격으로 도메인을 변경할 경우 서버 제공자의 신원 인증이 불가.

5) CA

공인 인증서 발급 기관

6) 비대칭키 암호(서버가 클라이언트에 전달)

전혀 다른 키 한쌍으로 암호화 및 복호화를 한다.
키 A로 암호화를 한다면 키 B로만 복호화가 가능. 암호화와 복호화에 서로 다른 키를 사용하는 방식.
서버는 키 하나는 보관, 다른 키는 클라이언트에 공개하여 데이터를 안전하게 전달할 수 있게 한다. (공개키 암호화)

publickey는 누구나 가지고 있을수 있음에도 이런 방식을 사용하는 이유는 공개키가 데이터 제공자의 신원을 보장해 주기 때문이다.
-암호화된 데이터가 공개키로 복호화 된다는 것은,공개 키와 쌍을 이루는 개인 키에 의하여 암호화 됬다는 것을 의미한다.즉 데이터 제공자의 신원 확인이 보장 된다는 것이다.

Hand Shake: 클라이언트는 서버로부터 공개키와 인증서 정보를 받는데, 인증서 정보로 인증된 서버인지 확인한다.
비밀키 부분: 클라이언트는 서버와 비밀 키를 만들어낼 정보를 암호화하여 전송한다. 서버도 마찬가지. 이를 이용하여 비밀키 생성.
상호키 검증: 비밀키를 이용하여 클라이언트가 서버에 암호화된 메세지 전달. 서버가 비밀키를 이용하여 이를 복호화하고 다시 암호화하여 클라이언트에게 보내는데, 클라이언트가 복호화에 성공하면 비밀 키가 성공적으로 만들어졌다는 뜻이다.
=> HTTPS 연결이 성립.

결론

이렇게 브라우저는 인증서의 도메인과 데이터를 제공한 제공자의 도메인을 비교할 수 있기 때문에 인증서의 도메인 정보와 데이터 제공자의 도메인 정보가 다른 '중간자 공격'을 감지하여 보안 위협으로부터 사용자 및 사용자의 데이터를 보호할 수 있습니다.
또한 이런 경고를 직접 보여줌으로써 브라우저들은 인증된 CA가 발급한 인증서를 이용하여 데이터를 제공하는 안전한 서버를 사용할 수 있게 사용자를 유도합니다.

인증서 발급 및 HTTPS 서버 구현


mkcert 프로그램을 이용하여 로컬환경(내 컴퓨터)에서 신뢰할 수 있는 인증서를 만들 수 있습니다.

인증서는 공개키, 그리고 인증기관의 서명을 포함하고 있으므로 공개되어도 상관이 없지만, key.pem의 경우 개인 키이므로 git에 커밋하지 않고, 암호처럼 다루어야 합니다.

key.pem => 키 (보관)
cert.pem => 인증서 (클라이언트에 전송)

HTTPS 서버 작성

1) node.js https 모듈이용
2) express.js 이용

const https = require('https'); const fs = require('fs'); const express = require('express'); const app = express(); https .createServer( { key: fs.readFileSync(__dirname + '/key.pem', 'utf-8'), cert: fs.readFileSync(__dirname + '/cert.pem', 'utf-8'), }, app.use('/', (req, res) => { res.send('Congrats! You made https server now :)'); }) ) .listen(3001);

Advanced 확인해보기

기존에 작성한 서버를 ngrok을 이용해서 HTTPS로 터널링을 시켜보세요.

  • ngrok이란 HTTP로 만들어진 서버를 HTTPS 프로토콜로 터널링 해주는 프로그램입니다.

Hashing

알고리즘을 이용하여 비밀번호의 암호화.
어떠한 문자열에 '임의의 연산'을 적용하여 다른 문자열로 변환하는 것

simple example

password를 서버에서 암호화하여 DB 에 넣는다.
-> cufhcufh 가 DB 에 저장된다.
-> 클라이언트로부터 받은 password 와 DB 에 저장되어 있는 password 를 대조한 후 response 한다.
-> 요청 받은 비밀번호의 해싱값과 DB 에 저장되어 있는 해싱된 비밀번호의 대조


암호화 철칙

SHA1, SHA256 등등 다양한 알고리즘이 존재한다.
SHA256 알고리즘을 사용했을 경우 출력값의 길이는 언제나 동일하다.
해시 알고리즘은 특정 입력 값에 대해 항상 같은 해시 값을 리턴한다. => 이 점을 이용하여 인증을 할 수 있는 것이다.
극히 드물게 다른 입력값인데 같은 해시값이 나올 수 있다.
해싱 알고리즘은 해독이 절대 불가하지는 않다.




Salt

주의할점

salt 예시


rainbow table


Cookie

서버가 클라이언트에 데이터를 저장할 수 있습니다.

쿠키는 서버에서 클라이언트에 데이터를 저장하는 방법으로 서버가 원한다면 서버는 클라이언트에서 쿠키를 이용하여 데이터를 가져올 수 있습니다.
즉, 단순히 서버에서 클라이언트에 쿠키를 전송하는 것만 의미하지 않고 클라이언트에서 서버로 쿠키를 전송하는 것도 포함됩니다.
사용자 선호, 테마 등 장시간 보존해야 하는 정보 저장에 적합. 로그인 상태 유지. 인증정보를 쿠키에 넣어서 저장하기도 함.

하지만 데이터를 저장한 이후 아무 때나 데이터를 가져올 수 없습니다.
데이터를 저장한 이후 특정 조건(아래의)들이 만족하는 경우에만 다시 가져올 수 있습니다.

Cookie Option

  1. Domain

    요청해야 할 URL이 http://www.localhost.com:3000/users/login 이라 하면Domain은 localhost.com이 됩니다.

    만약 쿠키 옵션에서 도메인 정보가 존재한다면 클라이언트에서는 쿠키의 도메인 옵션과 서버의 도메인이 일치해야만 쿠키를 전송할 수 있습니다.

     

  2. Path

    세부 경로는 서버가 라우팅할 때 사용하는 경로입니다. 만약 요청해야 하는 URL이 http://www.localhost.com:3000/users/login 인 경우라면 여기에서 Path, 세부 경로는 /users/login이 됩니다.

    명시하지 않으면 기본으로 / 으로 설정되어 있습니다.

    설정된 path를 전부 만족하는 경우 요청하는 Path가 추가로 더 존재하더라도 쿠키를 서버에 전송할 수 있습니다. 즉 Path가 /users로 설정되어 있고, 요청하는 세부 경로가 /users/login 인 경우라면 쿠키 전송이 가능합니다.

    하지만 /user/login으로 전송되는 요청은 Path 옵션을 만족하지 못하기 때문에 서버로 쿠키를 전송할 수 없습니다.

     

  3. MaxAge or Expires

    쿠키가 유효한 기간을 정하는 옵션입니다.

    Expires 은 MaxAge와 비슷합니다. 다만 클라이언트 시간을 기준으로 언제까지 유효한지 Date를 지정합니다.

    지정된 시간, 날짜를 초과하게 되면 쿠키는 자동으로 파괴됩니다.

    하지만 두 옵션이 모두 지정되지 않는 경우에는 브라우저의 탭을 닫아야만 쿠키가 제거될 수 있습니다.

     

  4. Secure: 쿠키를 전송해야 할 때 사용하는 프로토콜에 따른 쿠키전송 여부를 결정합니다. 만약 해당 옵션이 true로 설정된 경우, 'HTTPS' 프로토콜을 이용하여 통신하는 경우에만 쿠키를 전송 할 수 있습니다.

  5. HttpOnly

    만약 해당 옵션이 true로 설정된 경우, 자바스크립트에서는 쿠키에 접근이 불가합니다.

    명시되지 않는 경우 기본으로 false로 지정되어 있습니다. 만약 이 옵션이 false인 경우 자바스크립트에서 쿠키에 접근이 가능하므로 'XSS' 공격에 취약합니다.

     

  6. SameSite

    Cross-Origin 요청을 받은 경우 요청에서 사용한 메소드와 해당 옵션의 조합으로 서버의 쿠키 전송 여부를 결정하게 됩니다. 사용 가능한 옵션은 다음과 같습니다.

    • Lax :Cross-Origin 요청이면 'GET' 메소드에 대해서만 쿠키를 전송할 수 있습니다.

    • Strict : Cross-Origin이 아닌 same-site 인 경우에만 쿠키를 전송 할 수 있습니다.

    • None: 항상 쿠키를 보내줄 수 있습니다. 다만 쿠키 옵션 중 Secure 옵션이 필요합니다.

    이때 'same-site'는 요청을 보낸 Origin과 서버의 도메인이 같은 경우를 말합니다.

     

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

쿠키 기반 인증 (Cookie-based Authentication)

이러한 쿠키의 특성을 이용하여 서버는 클라이언트에 인증정보를 담은 쿠키를 전송하고, 클라이언트는 전달받은 쿠키를 요청과 같이 전송하여 Stateless 한 인터넷 연결을 Stateful 하게 유지할 수 있습니다.
하지만 기본적으로는 쿠키는 오랜 시간 동안 유지될 수 있고, 자바스크립트를 이용해서 쿠키에 접근할 수 있기 때문에 인증정보가 유출되기에 십상이었습니다.
따라서 오랫동안 클라이언트에 저장이 가능하다는 특징은 장점이자 단점이 되어서 쿠키에 인증 정보를 담아 보관하는 쿠키 기반 인증 방식은 많이 사용되지 않는 방법이 되었습니다.

삭제하지 않는한 영원히 보존된다. 로그인 유지 옵션 등 장시간 유지해야 하는 옵션의 구현에 유리하다.
스크립트를 이용하여 누구나 쉽게 접근할 수 있다.


Session


유저 인증정보는 더이상 쿠키에 담기지 않고 각각의 세션 객체에 저장됩니다. 따라서 로그인 이후 각각의 세션 객체에 해당 유저의 인증정보를 저장하는 로직이 필요합니다.
이렇게 유저 인증정보를 저장하고 나면, 서버는 매 요청마다 해당되는 세션 객체에 저장된 유저 인증정보를 바탕으로 유저정보 요청같은 인증이 필요한 요청이 이전에 인증된 유저의 요청인지 검증 할 수 있습니다.

쿠키를 통해서 유효한 세션 아이디가 서버에 전달되고, 세션 객체에 해당 세션 아이디에 유저의 인증정보가 존재한다면 서버는 해당 요청이 유저정보에 접근 가능하다고 판단합니다.

세션 아이디가 담긴 쿠키는 인터넷 탭을 닫으면 삭제되지만, 유효기간이 따로 정해져 있지 않습니다. 따라서 쿠키 안의 세션 아이디가 유출될 수 있으므로, 로그아웃 요청시 서버에서 세션을 파괴하는 과정이 반드시 필요합니다.

  • 서버에 접속 상태가 저장된다.
  • 세션은 보통 하나의 서버에서만 접속 상태를 저장한다. 여러개의 서버에서 같은 세션 데이터에 접근하려고 한다면 session clustering 을 사용해야 하는 번거로움이 있다. (불가능은 아님)
  • 신뢰할 수 있는 유저인지 확인 가능하다.
  • Cookie 에 세션 아이디가 저장된다.


Set-Cookie 란 무엇

서버는 Set-Cookie 헤더를 설정하여 응답과 함께 전송하고 쿠키는 브라우저에 저장됩니다. 즉, 서버는 아래와 같은 포맷으로 전송하는 것입니다.

HTTP/2.0 200 OK Content-type: text/html Set-Cookie: <cookie-name>=<cookie-value>


1) 클라이언트에서 로그인 요청을 하면 서버에서 connect.sid 객체(클라언)를 헤더의 set-cookie 에 담아보낸다.

로그인 요청시 response
 req.session.save(function () { //! session 에 userId 를 담아준다. req.session.userId = userInfo.userId; // console.log(req.session); res.json({ data: userInfo, message: "ok" }); });

userInfo.userId(여기에서 'kimcoding') 가 해싱되어 connect.sid 처럼 표현 되는 것이다.


2) 클라이언트는 이 객체를 이용하여 서버에 유저 정보를 요청한다.


쿠키는 헤더정보에 Set-Cookie의 실제값을 포함시켜 요청하고,
세션에서는 set-cookie에 connect.sid(이것이 세션 아이디. userId 값이 해싱되는 것으로 추정) 라는 식별자만(고유값)을 포함시켜 요청한다. (클라이언트에서 관리하는 정보가 다름)
클라이언트의 컴퓨터에는 중요한 정보는 저장되어 있지 않고, connect.sid라는 식별자 값만 저장되어 있으므로, 보안적으로 안전합니다.

express-session 모듈을 사용한 경우.

Session { cookie: { path: '/', _expires: 2021-01-24T09:47:59.370Z, originalMaxAge: 86400000, httpOnly: true, secure: true, domain: 'localhost', sameSite: 'None' }, userId: 'kimcoding' }

쿠키와 세션의 차이점

쿠키: 쿠키는 클라이언트의 상태정보를 로컬(client side)에 저장했다가 참조한다. 유효시간을 명시할 수 있는데, 브라우저가 종료되어도 인증은 유지된다.
세션: 세션은 쿠키를 기반하고 있지만, 해당 데이터는 서버에 저장되어 관리된다. 클라이언트를 구분하기 위해 세션 ID를 부여하는데 웹 브라우저가 종료될 때까지만 인증상태가 유지된다.



CSRF


Cross site request forgery

주소가 다른 사이트에서 유저가 보내는 요청을 조작하는 것.
...이메일에 첨부된 링크를 누르면 내 은행 계좌의 돈이 빠져나감.

유저가 보내는 요청을 다른 오리진에서 위조하는 것이다. 요청에 담길 데이터를 직접 바꾸는 것이 아니라 다른 임의의 endpoint 에 query parameter 만 변경하여 전송하는 방법이다. 즉, 어떤 메소드로 요청을 하는지, 어떠한 endpoint 에 요청을 보낼때 필요한 parameter 가 무엇인지만 안다면 요청을 위조하여 보낼 수 있다. (username 을 phillip 에서 hacker 로 변경...).
쿠키 방식의 인증을 사용하는 곳에서 사용이 가능하며 sameSite 옵션을 사용하면 많은 CSRF 공격을 방지할 수 있다.


해커가 직접 데이터에 접근할 수 없다. (다른 오리진이기 때문에 직접 response 에 접근 불가)

CSRF 공격 조건
1) 쿠키를 사용한 로그인: 쿠키로 어떤 유저인지 알 수 있어야 한다.
2) 예측할 수 있는 요청 /parameter 를 가지고 있어야 한다. request 에 해커가 모를 수 있는 정보가 담겨 있으면 안된다.

해커의 계좌번호로 이체를 요청한 것으로 판단.
비밀번호 변경을 요청한 것으로 판

CSRF 막는 방법?


TOKEN

토큰은 유저 정보를 암호화한 상태로 담을 수 있고, 암호화 했기 때문에 클라이언트에 담을 수 있습니다.

토큰기반 인증 중 대표적인 JWT (JSON Web Token)

JWT의 종류

  1. Access Token
  2. Refresh Token

Access token은 보호된 정보들(유저의 이메일, 연락처, 사진 등)에 접근할 수 있는 권한부여에 사용합니다. 클라이언트가 처음 인증을 받게 될 때(로그인시), access, refresh token 두가지를 다 받지만, 실제로 권한을 얻는데 사용하는 토큰은 access token 입니다.
access token에는 비교적 짧은 유효기간 을 주어 탈취 되더라도 오랫동안 사용할 수 없도록 하는것이 좋습니다.
Access token의 유효기간이 만료된다면 refresh token을 사용하여 새로운 access token을 발급 받습니다. 이때, 유저는 다시 로그인 할 필요가 없습니다.

유효기간이 긴 refresh token마저 악의적인 유저가 얻어낸다면 큰 문제가 될 것입니다. 상당히 오랜 기간동안 access token이 만료되면 다시 발급 받으며 유저에게 피해를 입힐 수 있기 때문이죠. 그렇기 때문에 유저의 편의보다 정보를 지키는 것이 더 중요한 웹사이트들은 refresh token을 사용하지 않는 곳이 많습니다.

JWT 구조

Header
Header는 이것이 어떤 종류의 토큰인지(지금의 경우엔 JWT), 어떤 알고리즘으로 sign(암호화) 할지가 적혀있습니다. JSON Web Token 이라는 이름에 걸맞게 JSON형태로 이런 형태를 보실 수 있습니다. 이 JSON 객체를 base64 방식으로 인코딩하면 JWT의 첫번째 부분이 완성됩니다.
어떤 종류의 토큰을 사용하는지 적혀있다.
어떤 알고리즘으로 암호화 하는지 적혀있다.

{ "alg": "HS256", "typ": "JWT" }


Payload
Payload에는 정보가 담겨 있습니다. 어떤 정보에 접근 가능한지에 대한 권한을 담을 수도 있고, 사용자의 유저이름 등 필요한 데이터는 이곳에 담아 암호화 시킵니다. 물론 암호화(헤더에서 정의한)가 될 정보지만, 민감한 정보(비밀번호, 민감한 개인정보)는 되도록 담지 않는 것이 좋습니다.

{ "sub": "someInformation", "name": "phillip", "iat": 151623391 }

첫번째 부분과 마찬가지로, 위 JSON 객체를 base64로 인코딩하면 JWT의 두번째 블럭이 완성됩니다.


Signature
base64로 인코딩 된 첫번째, 그리고 두번째 부분이 완성 되었다면, 원하는 비밀 키(암호화에 추가할 salt, secret)를 사용하여 암호화 합니다. base64 인코딩을 한 값은 누구나 쉽게 디코딩할 수 있지만, 서버에서 사용하고 있는 비밀키를 보유한게 아니라면 해독해내는데 엄청난 시간과 노력이 들어갈 겁니다!

Signature => 해쉬된 값으로 그 자체로 verified.

예를들어, 만약 HMAC SHA256 알고리즘(암호화 방법중 하나)을 사용한다면 signature는 아래와 같은 방식으로 생성됩니다.

HMACSHA256(base64UrlEncode(header) + '.' + base64UrlEncode(payload), secret);


JWT 모듈을 사용하여 Access Token 과 Refresh Token 을 만든 예

 const payload = { id: userInfo.id, userId: userInfo.userId, email: userInfo.email, createdAt: userInfo.createdAt, updatedAt: userInfo.updatedAt, }; const access_token = jwt.sign(payload, process.env.ACCESS_SECRET, { expiresIn: "1d", }); const refresh_token = jwt.sign(payload, process.env.REFRESH_SECRET, { expiresIn: "10d", }); res .status(200) .cookie("refreshToken", refresh_token, { domain: "localhost", path: "/", httpOnly: true, secure: true, sameSite: "none", }) .json({ data: { accessToken: access_token }, message: "ok" });


JWT 사용 예시

JWT는 권한 부여에 굉장히 유용합니다.. 새로 다운받은 A라는 앱이 Gmail과 연동되어 이메일을 읽어와야 한다고 생각해 봅시다. 유저는

  1. Gmail 인증서버에 로그인정보(아이디, 비밀번호)를 제공한다
  2. 성공적으로 인증시 JWT 를 발급받는다
  3. A앱은 JWT를 사용해 해당 유저의 Gmail 이메일을 읽거나 사용할 수 있다

토큰기반 인증 절차

  1. 클라이언트가 서버에 아이디/비밀번호를 담아 로그인 요청을 보낸다.
  2. 아이디/비밀번호가 일치하는지 확인하고, 클라이언트에게 보낼 암호화된 토큰을 생성한다.
    • access/refresh 토큰을 모두 생성한다.
      • 토큰에 담길 정보(payload)는 유저를 식별할 정보, 권한이 부여된 카테고리(사진, 연락처, 기타등등)이 될 수 있다.
      • 두 종류의 토큰이 같은 정보를 담을 필요는 없다 (이 스프린트에서는 같은 정보를 담아줍시다).
  3. 토큰을 클라이언트에게 보내주면, 클라이언트는 토큰을 저장한다.
    • 저장하는 위치는 local storage, cookie, react의 state 등 다양하다.
  4. 클라이언트가 HTTP 헤더(authorization 헤더)에 토큰을 담아 보낸다.
  5. 서버는 토큰을 해독하여 "아 우리가 발급해준 토큰이 맞네!" 라는 판단이 될 경우, 클라이언트의 요청을 처리한 후 응답을 보내준다.

토큰기반 인증의 장점

  1. Statelessness & Scalability (무상태성 & 확장성)
    • 서버는 클라이언트에 대한 정보를 저장할 필요 없습니다 (토큰 해독이 되는지만 판단합니다)
    • 클라이언트는 새로운 요청을 보낼때마다 토큰을 헤더에 포함시키면 됩니다
      • 서버를 여러개 가지고 있는 서비스라면 더더욱 빛을 발휘합니다 (같은 토큰으로 여러 서버에서 인증 가능)
  2. 안전하다
    • 암호화 한 토큰을 사용하고, 암호화 키를 노출 할 필요가 없기 때문에 안전합니다
  3. 어디서나 생성 가능하다
    • 토큰을 확인하는 서버가 토큰을 만들어야 하는 법이 없습니다
    • 토큰 생성용 서버를 만들거나, 다른 회사에서 토큰관련 작업을 맡기는 것 등 다양한 활용이 가능합니다
  4. 권한 부여에 용이하다
    • 토큰의 payload(내용물) 안에 어떤 정보에 접근 가능한지 정할 수 있습니다
      • ex) 서비스의 사진과 연락처 사용권한만 부여


질문

  • 만료된 토큰은 어떻게 확인할 수 있을까요?
  • 다른 누군가가 만료된 토큰을 이용하는걸 막는 방법은 없을까요?
  • 만료된 토큰은 어떻게 처리해야 할까요?
  • 토큰이 유출되지 않았음을 확인할 수 있을까요?
  • 토큰을 만드는 비밀키는 주기적으로 교체해야 할까요?

세션 VS 토큰

세션기반 인증은 서버(혹은 DB 통합)에 유저에 대한 정보를 저장하고 있다. 즉 메모리 공간을 서버쪽에서 차지하고 있고, 자원을 사용하고 있으므로 유저가 많을수록 성능이 떨어지기 마련이다. (토큰에 비해 상대적으로).
안전성을 비교할 수는 없지만, 앱의 확장을 고려한다면 토큰 기반 인증을 사용하는 것을 고려해야 할 것이다.

토큰 은 세션에 비해...
서버의 부담을 덜어줄 수 있다.
여러개의 서버를 사용하는 서비스를 운영할 때 좋다.
앱의 확장을 고려하여 유리하다.


OAuth


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

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

OAuth는 인증(Authentication)을 다른 서비스에 맡길 뿐, 접근 권한 관리(Authorization)는 순전히 내 서버의 몫입니다.

질문: Authentication과 Authorization의 차이가 무엇인가요?

OAuth 란?

OAuth2.0은 인증을 위한 표준 프로토콜의 한 종류 보안 된 리소스에 액세스하기 위해 클라이언트에게 권한을 제공(Authorization)하는 프로세스를 단순화하는 프로토콜 중 한 방법입니다.

OAuth 는 언제, 왜 쓸까요?

OAuth 를 활용한다면 자주 사용하고 중요한 서비스들(예를 들어 google, github, facebook) 의 ID와 Password만 기억해 놓고 해당 서비스들을 통해서 소셜 로그인을 할 수 있습니다. 매우 편리하죠?
뿐만 아니라 OAuth는 보안상의 이점도 있습니다. 검증되지 않은 App에서 OAuth를 사용하여 로그인한다면, 직접 유저의 민감한 정보가 App에 노출될 일이 없고 인증 권한에 대한 허가를 미리 유저에게 구해야 되기 때문에 더 안전하게 사용할 수 있죠.

OAuth에서 꼭 알아야 할 용어

  • Resource Owner : 액세스 중인 리소스의 유저입니다. 김코딩의 구글 계정을 이용하여 App에 로그인을 할 경우, 이 때 Resource owner은 김코딩이 됩니다.
  • Client : Resource owner를 대신하여 보호된 리소스에 액세스하는 응용프로그램입니다. 클라이언트는 서버, 데스크탑, 모바일 또는 기타 장치에서 호스팅할 수 있습니다.
  • Resource server : client의 요청을 수락하고 응답할 수 있는 서버입니다.
  • Authorization server : Resource server가 액세스 토큰을 발급받는 서버입니다. 즉 클라이언트 및 리소스 소유자를 성공적으로 인증한 후 액세스 토큰을 발급하는 서버를 말합니다.
  • Authorization grant : 클라이언트가 액세스 토큰을 얻을 때 사용하는 자격 증명의 유형입니다.
  • Authorization code : access token을 발급받기 전에 필요한 code 입니다. client ID로 이 code를 받아온 후, client secret과 code를 이용해 Access token 을 받아옵니다.
  • Access token : 보호된 리소스에 액세스하는 데 사용되는 credentials입니다. Authorization code와 client secret을 이용해 받아온 이 Access token으로 이제 resource server에 접근을 할 수 있습니다.
  • Scope : scope는 토큰의 권한을 정의합니다. 주어진 액세스 토큰을 사용하여 액세스할 수 있는 리소스의 범위입니다.

OAuth 앱을 등록하면 이와 같이 Client ID 와 Client secret 을 발급 받을 수 있다.



질문: Authorization callback URL은 무엇인가요?

  • OAuth 메커니즘이 인증 과정이 끝난 후 리디렉션을 통해 다시 내 앱으로 이동하는 원리이므로, 내 앱으로 돌아가기 위한 Authorization callback URL이 필요합니다.

'BootCamp_Codestates > IM Tech Blog' 카테고리의 다른 글

11. Databases  (0) 2021.01.13
10. Redux  (0) 2021.01.11
8-1. React 데이터흐름 & State 끌어올리기  (0) 2021.01.05
8. React Part1  (0) 2021.01.01
5. Asynchronous & Promise  (0) 2020.12.21
Comments