본문 바로가기

프로그래머스 풀스택 데브코스/데브코스 TIL

웹 풀사이클 데브코스 TIL 27일차

인증 vs 인가

인증

Authentication. 로그인. 사이트에 가입된 사용자라는 걸 증명
예시) 쇼핑몰 상품 구매, 마이페이지

인가

Authorization. 허가. 인증 후에 페이지 접근 권한이 있나?
예시) 관리자 / 고객 에 따라 접근할 수 있는 페이지가 다르다.

쿠키

쿠키: 서버와 클라이언트가 주고받는 정보

로그인 -> 서버가 쿠키를 구워줌
사용자 <-> 서버 쿠키를 주고받음

  • 장점: 서버가 저장 X => 서버 저장공간 X, Stateless 하다 => RESTful 하다
  • 단점: 보안 취약

세션

세션: 로그인이 되어있는 상태

로그인 -> 서버가 금고를 만들어서 정보 저장하고 금고 번호를 줌
사용자 <-> 서버가 번호만 가지고 대화

  • 장점: 보안 비교적 좋다
  • 단점: 서버가 저장 O => 서버 저장공간, Stateless X

JWT

JSON Web Token

  • 개념: JSON 형태의 데이터를 안전하게 전송하기 위한 웹에서 사용하는 토큰
    = 토큰을 가진 사용자가 '증명'을 하기 위한 수단
    cf. 토큰: (인증용) 입장/ (인가용) 권한
  • 장점: 보안에 강하다 = 암호화가 되어있다, Stateless 하다 = HTTP 특징을 잘 따랐다.

공식 사이트: https://jwt.io/

구조

헤더: 토큰을 암호화하는데 사용한 알고리즘, 토큰의 형태(jwt)
페이로드: 사용자 정보(이름, 주소, 번호, 비밀번호 빼고 마음대로)
서명: 페이로드 값이 변경되면 서명값도 같이 바뀜

구현

npm 에서 jsonwebtoken 패키지를 설치해서 사용한다.
링크: https://www.npmjs.com/package/jsonwebtoken

var jwt = require('jsonwebtoken'); //jwt 모듈 소환
 // 서명 = 토큰 발행
var token = jwt.sign({ foo: 'bar' }, 'shhhhh');
//token 생성 = jwt 서명 (페이로드, 나만의 암호키) + SHA256
console.log(token);
//검증
// 만약 검증에 성공하면, 페이로드 값을 확인할 수 있음
var decoded = jwt.verify(token, 'shhhhh');
console.log(decoded);

페이로드에 foo 값을 넣고 'shhhhh' 라는 개인키를 넣어서 암호화 시킨다.
토큰을 디코드 할 수도 있다. 디코드 시에도 마찬가지로 개인키를 인자로 전달해야한다.

.env(environment: 환경 변수 '설정 값')

  • 개념: 개발하다가 포트넘버, 계정, 암호키 등등 외부에 유출되면 안되는 중요한 환경변수들을 따로 관리하기 위한 파일
  • 위치: .env 파일은 프로젝트 최상위 패키지에 존재
//.env 파일
PRIVATE_KEY = 'shhhhh' # JWT 암호키
PORT = 3000 # express 포트넘버

이름은 스네이크 케이스로 대문자로 작성하는게 원칙이다.

var jwt = require('jsonwebtoken'); //jwt 모듈 소환
var dotenv = require('dotenv')

dotenv.config();

 // 서명 = 토큰 발행
var token = jwt.sign({ foo: 'bar' }, process.env.PRIVATE_KEY);
//token 생성 = jwt 서명 (페이로드, 나만의 암호키) + SHA256

console.log(token);

//검증
// 만약 검증에 성공하면, 페이로드 값을 확인할 수 있음

var decoded = jwt.verify(token, process.env.PRIVATE_KEY);
console.log(decoded);

자바스크립트에서 사용하는 방법은 다음과 같다. require로 모듈을 가져오고 config()를 불러주어야한다. 그 후에 process.env.변수이름 의 형식으로 사용한다.

Cookie

conn.query(sql , email,
    function(err, results) {
        if(err) {
            console.log(err)
            return res.status(400).end()
        }
        let loginUser = results[0]

        if(loginUser && loginUser.password == password){
            //token 발급
            const token = jwt.sign({
                email : loginUser.email,
                name : loginUser.name
            }, process.env.PRIVATE_KEY, {
                expiresIn : '30m',
                issuer : "jh"
            })

            res.cookie("token", token,{
                httpOnly: true
            })

            res.status(200).json({
                message : `${loginUser.name}님 로그인 되었습니다.`
            })
        }
        else{
            res.status(403).json({
                message : `이메일 또는 비밀번호가 틀렸습니다.`
            })
        }
    }
)

token을 발급할때 만료시간과 발행자까지 추가해서 발급하였다. 그후 쿠키에 이 값을 싣어서 보내고 httpOnly 옵션도 true로 설정하였다. 마지막으로 계정정보가 틀렸을 경우 403 에러를 내려준다.

다음은 Postman의 쿠키 옵션들이다.

HttpOnly : 프론트엔드가 아니라 API 만 허용할것인가?
Secure: https를 사용할 것인가?

키워드: 프로그래머스 데브코스, 국비지원교육, 코딩부트캠프