인증과 인가
1. 인증 (=로그인) Authentication
1-1 세션(Session) : 로그인이 되어있는 상태
- 과정: 로그인 시 서버가 정보를 저장하고 안전한 번호를 생성하여 제공. 사용자와 서버는 해당 번호로 통신.
- 장점: 보안이 상대적으로 우수.
- 단점: 서버가 저장하므로 서버 저장 공간 필요, 상태 유지 어려움.
1-2 쿠키(Cookies)
- 과정: 웹 서버가 생성하고 웹 브라우저가 저장하며, 다음 웹 서버 방문 시 쿠키를 통해 로그인 가능.
- 장점: 서버 저장 공간 필요 없음, 상태 유지 용이 (HTTP/stateless, RESTful).
- 단점: 쿠키가 브라우저에 저장되므로 보안이 상대적으로 취약.
1-3 JWT : Json Web Token
개념
Json 형태의 데이터를 안전하게 전송하기 위해 웹에서 사용하는 토큰
토큰: (인증용) 입장 가능한 유저 / (인가)관리자 권한or일반유저 권한 부여용
= 토큰을 가진 사용자가 증명을 하기 위한 수단
구성요소
- Header: 토큰 암호화에 사용되는 알고리즘 및 토큰 타입 (예: JWT).
- Payload: 사용자 정보 등.
- Signature: Payload 값이 변경되면 전체 시그니처 값이 변경되므로 신뢰성 유지 가능.
.
장점
- 보안에 강하다 (암호화가 되어있다.)
- HTTP 특징을 잘 따랐다. stateless하다 => 서버가 상태를 저장하지 않는다.
- 서버 부담을 줄여줄 수 있고.
토큰을 발행하는 서버를 따로 만들어줄 수도 있음.
어떤 알고리즘인지 알고 서버에 치명적인 데이터를넣으려고 한다면? 이라는 의문을 가질 수 있다.
하지만 payload가 바뀐다면 아래 파란색 부분인 서명이 바뀐다. => 서명이 틀린 경우, 서버에서 받아주지 않기 때문에 그런 일은 발생하지 않는다.
2. 인가 Authorization
같은 사이트 내에 관리자/고객에 따라 접근할 수 있는 페이지가 다르다.
관리자든 고객이든 인증을 통해서 사이트에 가입된 사용자라는걸 증명하는 것이다. 즉, 인증 후에 페이지 접근 권한 있는가를 확인하는 것.
예시
jwt로 인증/인가 하는 절차
=> 로그인 성공, 로그인 당분간 유지.
Synchronous Sign with default (HMAC SHA256) => 디폴트 알고리즘
JWT 토큰 만들어보기
https://www.npmjs.com/package/jsonwebtoken
jsonwebtoken
JSON Web Token implementation (symmetric and asymmetric). Latest version: 9.0.2, last published: 4 months ago. Start using jsonwebtoken in your project by running `npm i jsonwebtoken`. There are 26035 other projects in the npm registry using jsonwebtoken.
www.npmjs.com
var jwt = require("jsonwebtoken");
var token = jwt.sign({ id: "bsu0404" }, "shhhhh");
console.log(token);
암호화 payload와 PrivateKey을 넣어준다. 옵션으로 알고리즘을 설정하지 않으면 디폴트 알고리즘으로 만들어진다.
결과
token 확인 1) - jwt 사이트에서
jwt 사이트에서 인코드된 값을 넣어주면 header와 payload, signature 가 나온다.
token 확인 2) - 코드로 검증하기
let decoded = jwt.verify(token, "shhhhhh");
console.log(decoded);
결과:
.env (environment: 환경변수 '설정값')
- 개념
개발을 하다가 포트번호, 데이터베이스 계정, 암호키 등등 외부에 유출되면 안되는 중요한 환경변수를 관리하기 위한 파일
(깃허브에 올라가면 안되는 값)
https://www.npmjs.com/package/dotenv
dotenv
Loads environment variables from .env file. Latest version: 16.3.1, last published: 6 months ago. Start using dotenv in your project by running `npm i dotenv`. There are 38862 other projects in the npm registry using dotenv.
www.npmjs.com
.env는 최상위 폴더에 위치!
공식문서대로 대문자, snakecase로 써주면 좋을 것이다.
다른 파일에서 process.env.[이름]으로 사용한다.
.env
PRIVATE_KEY = "shhhhhh" #JWT 암호키
jwt.js
var jwt = require("jsonwebtoken");
let dotenv = require("dotenv");
dotenv.config();
var token = jwt.sign({ foo: "bar" }, process.env.PRIVATE_KEY);
참고 - config() 함수는?
- dotenv 라이브러리의 메서드로, 주어진 파일에서 환경 변수를 로드하고 현재 프로세스의 환경 변수에 추가함.
- 즉, .env 파일에서 환경 변수를 로드하고 있음. => 이 파일에는 PRIVATE_KEY라는 환경 변수가 정의되어 있어서 jwt.sign 메서드에서 사용됨
쿠키에 토큰 담아주기
https://www.npmjs.com/package/cookie-parser
cookie-parser
Parse HTTP request cookies. Latest version: 1.4.6, last published: 2 years ago. Start using cookie-parser in your project by running `npm i cookie-parser`. There are 8524 other projects in the npm registry using cookie-parser.
www.npmjs.com
jsonwebtoken외부 모듈와 dotenv외부 모듈을 이용해 sign한 뒤 cookie-parser 외부 모듈을 이용해 cookie에 보내준다.
///로그인
router.post(
"/login",
[
body("email").notEmpty().isEmail().withMessage("email must be a string."),
body("pw").notEmpty().isString().withMessage("pw must be a string"),
validate,
],
(req, res) => {
let { email, pw } = req.body;
let sql = `SELECT * FROM users WHERE email = ? `;
conn.query(sql, email, function (err, results) {
if (err) {
console.log(err);
return res.status(400).send();
}
let loginUser = results[0];
if (loginUser && loginUser.pw == pw) {
//토큰 발급
const token = jwt.sign(
{
email: loginUser.email,
name: loginUser.name,
},
process.env.PRIVATE_KEY
);
res.cookie("token", token);
res.status(200).json({ message: `${loginUser.name}님 환영합니다.` });
} else {
res.status(403).json({
message: "id 및 pw를 확인해주세요.",
});
}
});
}
);
참고
403 - 서버에서 설정해 둔 권한과 맞지 않는 접속 요청이 들어오면 접근을 거부하고 접근거부 코드를 반환하는데, 이 때 뜨는 것이 바로 403 Forbidden이다.
Cookie 살펴보기
1. Value?
value에서 토큰값을 확인할 수 있다.
2. Secure?
네이버에서 상단 부분을 눌러보면 아래와 같이 인증서가 있고, 믿을만한 user인지 암호화하여 http프로토콜을 보내도록 한 것이 https이다. 이 경우는 secure가 true
3. httpOnly?
httpOnly(=API 호출만 허락): XSS 공격(프론트엔드 공격: 웹브라우저 js접근)
httpOnly가 true면 api로만 가능
res.cookie("token", token, {
httpOnly: true,
});
이같이 cookie에 옵션을 추가하면 httpOnly옵션이 true로 바뀐다.
발행인 추가하기, 만료시간 추가
발행인 - sign할 때 issuer를 추가
만료시간 - sign할 때 expireIn 추가
const token = jwt.sign(
{
email: loginUser.email,
name: loginUser.name,
},
process.env.PRIVATE_KEY,
{
expiresIn: "5m",
issuer: "sungeun",
}
);
jwt.io사이트에서 확인 가능하다.
위와 비교해보면 payload에 iss에 발급자, exp에 만료시간이 추가된 것을 확인할 수 있다.
'타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js) > TIL' 카테고리의 다른 글
웹 풀사이클 26일차 - API 설계 (0) | 2023.12.30 |
---|---|
웹풀사이클 25일차 - (0) | 2023.12.30 |
웹 풀사이클 23일차 - 유효성검사 적용, 미들웨어 next (3) | 2023.12.24 |
웹풀사이클 22일차 - workbench로 유튜브 채널, user (0) | 2023.12.23 |
웹 풀사이클 21일차 - MARIADB로 게시판 만들기 (0) | 2023.12.22 |