sprint-auth-token 서버위주 진행흐름

flobeeee·2021년 3월 12일
4

Sprint

목록 보기
22/25

🎯 인증방식의 흐름

  1. 쿠키기반인증은 쿠키에 유저정보를 담는 방식
    -> 쿠키 탈취되면 심각한 위험초래

  2. 세션기반인증은 서버(혹은 DB)에 유저정보를 담고,
    해당 정보를 확인할 수 있는 세션ID를 쿠키에 담는 방식
    -> 쿠키를 가져오면 쿠키에 있는 세션ID를 확인해서 유저정보 보여줌
    -> 마찬가지로 쿠키가 탈취되면 위험 + 서버에 정보담는 방식이라 서버에 부담

  3. 토큰기반인증은 유저정보를 암호화해서 클라이언트에 담음

🎯 JWT (JSON Web Token)

토큰기반 인증 중 가장 대표적인 방법
JSON 포맷으로 사용자에 대한 속성을 저장하는 웹 토큰

  • JWT 구조 (header.payload.signature)
  1. Header
    어떤종류의 토큰인가
    어떤 알고리즘으로 암호화 하는가
{
  "alg": "HS256",
  "typ": "JWT"
}
  1. Payload
    유저의 정보 (되도록 민감한 정보 안담는게 좋음)
    권한을 부여받았는가
    기타 필요한 정보
{
  "sub": "someInformation",
  "name": "phillip",
  "iat": 151623391
}
  1. Signature
    header와 payload를 base64 인코딩한 값과 salt 값의 조합으로 암호화된 값
HMACSHA256(base64UrlEncode(header) + '.' + base64UrlEncode(payload), secret);
  • JWT의 종류
  1. Access Token
    정보들에 접근할 수 있는 권한부여에 사용
  2. Refresh Token
    Access Token 이 만료되면 Refresh Token 으로 재발급
    때문에 Refresh Token 이 유효기간이 더 김
  • JWT 사용방법
    클라이언트가 로그인할때 access, refresh token 둘다 받음
    access token 으로 정보들에 접근하다가 만료되면 refresh token 을 사용해
    새로운 access token 발급받음 = 다시 로그인할 필요 없음
    그러나 토큰도 탈취의 위험이 있어서, 유저의 편의보다 정보를 지키는 것이 더 중요한 웹사이트들은 refresh token 을 사용하지 않기도 함

세션인증방식보다 토큰인증방식이 더 안전하다고 말할 수 없다.
각각의 인증방식의 장단점을 인지하고 적절하게 쓰는 것이 좋다.

🎯 스프린트 진행 흐름

  • 서버
  1. index.js https 서버 구현
  2. package.json 위치에 인증서 파일 가져오기(key.pem,cert.pem)
  3. .env 에 데이터베이스에 환경변수 설정(데이터베이스 이름 및 비밀번호 등)
  4. controllers/users/login.js 에서 POST / login 구현
    req.body에 아이디와 비밀번호가 들어오니까 DB를 확인해서
    데이터가 없는경우, 응답작성
    데이터가 있는경우, access token, refresh token 생성
    access 는 응답에 넣어주고, fresh 는 쿠키에 넣어주기
    (클라이언트에서 그렇게 다루기때문)
// jsonwebtoken 라이브러리를 사용해 토큰을 생성하는 방법
const jwt = require('jsonwebtoken');
const token = jwt.sign(토큰에_담을_값, ACCESS_SECRET, { 옵션1:, 옵션2:, ... });

// 작성한 코드
var jwt = require('jsonwebtoken'); // 이건 맨위에 이미 작성되어 있었음

const Payload = {
  id,
  userId,
  email,
  createdAt,
  updatedAt,
  iat: 151623391, // 이건 예제에서 가져옴
  exp: Math.floor(Date.now() / 1000) + (60 * 60) // 구글링해서 형식 찾음
} 
// 데이터베이스에서 가져온 정보가 페이로드에 들어가면 된다. 

const accessToken = jwt.sign(Payload, process.env.ACCESS_SECRET);
const refreshToken = jwt.sign(Payload1, process.env.REFRESH_SECRET);
// refreshToken 은 accessToken 보다 유효기간이 더 길게 설정한 Payload1을 넣어줬다.
res.set("Set-Cookie", [`refreshToken=${refreshToken} 쿠키설정주르륵~;`])
res.status(200).json(result);
// 리프레시 토큰은 이런식으로 쿠키에 담았다.
  1. controllers/users/accessTokenRequest.js 에서
    헤더에 발급한 토큰이 들었는지 확인하고, 있으면 정보조회 후 해당유저정보 보내주기
const authorization = req.headers['authorization'];
// 토큰이 있으면 authorization 에 값이 들어있음

// 토큰 해독하는 법 verify(해독, 검증)

const jwt = require('jsonwebtoken);

const authorization = req.headers['authorization'];

const token = authorization.split(' ')[1];
const data = jwt.verify(token, ACCESS_SECRET);

// 작성한 코드
const jwt = require('jsonwebtoken);

const authorization = req.headers['authorization'];

const token = authorization.split(' ')[1];
const tokenInfo = jwt.verify(token, process.env.ACCESS_SECRET)
console.log(tokenInfo) // 하면 넘겨줬었던 정보들 다 확인가능하다
// 담겨있는 정보를 DB와 조회후 존재하면 정보 넘기기
  1. controllers/users/freshTokenRequest.js 에서
    쿠키에 발급한 토큰이 들었는지 확인하고,
    있으면 accessToken 새로 발급해주고 유저정보 내보내기
const token = req.cookies.refreshToken;
// 이 코드로 쿠키에 리프레시토큰이 들어있는지 확인합니다

jwt.verify(token, process.env.REFRESH_SECRET) // 해독방법 같음

제일 중요한건 정보를 내보낼 때, 비밀번호를 내보내면 절대 안됩니다!

  • 클라이언트

테스트항목에 맞춰서, 상태업데이트하게 연결해주면 된다.
쿠키, 세션 클라이언트와 매우 비슷하다.

profile
기록하는 백엔드 개발자

0개의 댓글

Powered by GraphCDN, the GraphQL CDN