인증, 세션, 쿠키 개념정리
(이전글 : https://fashionking.tistory.com/398 )
0.
이전 시간까지는 웹서버에서 유저정보와 비밀번호를 받아
DB에 저장된 해싱된 비밀번호와 비교하여 Log in하는 과정까지를 알아보았다.
사용자의 (1).회원가입SignUp과 (2).LogIn이 되었다면..
이제 무엇을 해야할까?
1.
(3)번째 단계는 Authentication이다.
권한이 있는 사람들만 접근할 수 있는 페이지와 리소스에 대해서 권한을 인가Grant해주는
과정을 거쳐야 한다.
2.
하지만, 웹 사이트의 특정 부분을 어떻게 잠그고(Lock down)
특정 유저에게만 허가해줄까?
그걸 백앤드 단에서 구현하여야 하고,
User Auth Status, 사용자 인증 상태를 도입하고
Ticketing 개념을 활용하 이러한 권한을 부여해줄 수 있다.
3.
비행기를 예약하는 상황을 생각해보자.
- (0) 만약 당신이 비행기 티켓을 예약한다면,
- (1) 회사에서는 DB에 이러한 티켓에 대한 정보를 저장하고
- (2) 당신은 스마트폰이나 이메일을 통해 이러한 티켓을 받는다.
- (3) 그리고 실제로 공항에서 수속할때, 이 티켓을 회사에 보여준다면
회사에서 당신에게 비행기를 탈 수 있도록 허용해줄 것이다.
4.
웹서버도 동일하다.
- (0) 사용자가 특정 사이트에 대한 '티켓'을 요청한다면
- (1) 웹서버에서는 이러한 '티켓'을 생성하여 DB에 저장하고
- (2) 이 티켓의 'id'값을 유저에게 전달하고
- (3) 실제로 웹사이트의 리소스에 접근할 때, 유저가 이 'id'값을 보여주면
서버에서 유저에게 보호된 리소스를 사용할 수 있는 권한을 주는 것이다.
5.
그래서 서버사이드에서 아래와 같이
ticket을 확인하는 과정을 넣어주면, authentication 작업이 완료된다.
router.get('/admin', function (req, res) {
// check the user ticket
...
// render admin page
res.render('admin');
}
6.
그리고 이러한 ticket을 웹서버에서는 세션Session이라고 부른다.
세션은 서버에서 생성하는 티켓이다.
클라이언트(User/Browser) <-> 서버 <-> 데이터베이스 및 저장소
관계에서
유저는 로그인 과정에서 Login credential(로그인 인증데이터)을 서버에 보내고,
서버는 이러한 Credential이 유효한지 판단한 뒤,
(1) DB에 유저와 관련된 unique ID를 가진 티켓의 레코드, 세션을 저장하고
(2) 유저에게 response로 Session ID가 담긴 Cookie를 반환한다.
7.우리는 Cookie를 많이 접했다.
쿠키는 추적 및 광고에 쓰이는 민감한 정보이기도 하지만,
단순히 인증(Auth)에 사용되기도 한다.
브라우저는 서버단에 저장된 Session ID를 쿠키를 통해 알수 있으
이러한 Session ID를 이용해 후속 Request를 웹서버에 요청할 수 있다.
8.
이러한 세션과 쿠키를 통해서 클라이언트는 서버와 상호작용한다.
DB상의 세션에서 장바구니(Shopping Cart)정보를 저장할 수도 있고
서버의 리소스에 접근하는 권한을 Grant해주는 것도 가능해진다.
9.
세션은 서버단의 구조물(Construct)이며
클라이언트의 여러가지의 쿠키 중
세션 쿠키는 세션ID를 저장하는 중요쿠키이다.
클라이언트를 DB의 특정 세션에 대응하는 역할을 수행하며
동적으로 자주 변경되는 클라이언트의 IP보다
훨씬 Long Lived 데이터이다.
Fixed데이터이며, 브라우저에 몇개월씩 변경되지 않고 저장되는 데이터이다.
(다른 쿠키들은 개인정보를 훔쳐다가 맞춤형 광고랑 데이터 분석용으로 써먹으려고 하는
성가신 쿠키들이다)
10.
한가지 명심할 점은,
Sessions & Cookies가 오직 인증(Authentication)을 위해서만 쓰이지 않는 다는 점이다.
인가되지 않은 Unauthenticated User들도 세션을 할당받을 수 있다.
서버에서는 몇몇 세션들이 서버상에서 리소스를 받을 권한을 Grant받아서
{"isAuthenticated":true}와 같이 접근권한 플래그가 켜져있는 형태로 존재하며
보통 데이터베이스나 세션관리소에서 테이블이나 json형식으로 저장된다.
CREATE TABLE sessions (
session_id VARCHAR(128) NOT NULL PRIMARY KEY, -- 세션 ID
session_data TEXT NOT NULL, -- 세션에 저장된 데이터
last_access TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP -- 마지막 접근 시간
);
또 클라이언트에서는 몇몇 쿠키들이 세션들과 대응되고 연관되어 있을 뿐,
앞서말한 광고용 쿠키, 데이터분석용 쿠키 등 다른 용도로도 사용되는 쿠키들도 있다.
쿠키란 그저 브라우저상에서 클라이언트의 정보를 저장하는 key-value 텍스트 데이터일 뿐이며
브라우저마다 쿠키의 형식도 조금씩 다르다는 점을 알아두자.
15.
NodeJS에서는 이러한 세션관리를 용이하게 해주는 서드파티 패키지들이 존재하는데
express-session 패키지가 가장 대중적이며,
cookie-parser 패키지를 조합하여 사용한다면
서버단에서 편하게 세션과 쿠키를 관리할 수 있다.
16.
express-session을 이용한 세션기능 구현 예시
const express = require('express');
const session = require('express-session');
const mongodbStore = require('connect-mongodb-session');
const db = require('./data/database');
const MongoDBStore = mogodbStore(session);
const app = express();
...
const sessionStore = new MongoDBStore({
uri : 'localhost:27017',
databaseName: 'auth-demo',
collection : 'sessions'
cookie:{
maxAge: 30 * 24 * 60 * 1000, // 쿠키 expiration option,단위 ms, 쿠키만료 30일설정시
}
});
...
app.use(session({
secret: 'some-any-user-set-password', // 세션위조를 막기위한 암호설정
resave: false; // db에서만 세션이 업데이트 되도록 설정, 서버과부하시 빈 세션 덮어쓰기 방지
saveUninitializaed: false; // 세션이 DB에서만 저장되도록
store: ; //매우 중요함 // 어디에 세션이 저장될지 설정. 메모리, DB, 외부 파일저장소 등
}));
...
router.post('/login', async function (req, res){
const userData= req.body;
...
// 로그인 성공시
// 세션생성
req.session.user = { id: existingUser._id , email: existingUser.email };
req.session.isAuthenticated = true;
req.session.save(function(){
res.redirect('/admin'); // DB에서 세션이 생성된 이후에만 /admin 페이지로 리다이렉트
})
}
17.
인증된 유저의 admin 페이지 접근과
로그아웃 기능 구현
router.get('/admin', function (req,res) {
if (!req.session.isAuthenticated) {
return res.status(401).render('401');
}
res.render('admin');
});
router.post('/logout', function (req, res){
req.session.user = null;
req.session.isAuthenticated = false;
res.redirect('/');
});
18. 인증(Authentication) vs 권한부여(Authorize)
이때까지 인증(Auth)에 대해서 배웠지만,
인증을 받는 것과, 권한을 부여(Grant)받는 것은 다른 개념이다.
Authentication은 서버에게 유저가 자격 증명(Credential)을 제공하여
절차대로 DB의 ID와 PW를 비교하고 DB에 세션이 생성되는 과정을 거친
Valid User를 판별하는 과정이고
Authorization은 인증된 사용자가 특정 지소스에 접근할 권한이 있는지 확인하는 과정이며..
인증(Authenticated)된 사용자도 권한이 없다면 거부를 당할 수가 있다.
19.
가령 내가 ID카드를 찍어야만 들어갈 수 있는 회사(서버)에 그냥 들어가서
B팀 관리부원들의 명단이 저장된 DB를 조회하는 과정을 거부당했다고 하자..
이런 경우에는 내가 Unautenticated User라서 Authentication을 거치지 않은 것이 원인이고
회사에게서 401Forbidden Response를 받고
퇴짜맞은 것이라고 볼 수 있다.
20.
반면 내가 회사원의 A팀 사원으로서 ID카드를 제대로 발급받아서(Authenticated)
들어갔는데도, B팀 사원들의 명단을 조회하는 것을 거부당했다면
이런경우에는, 내가 인증된 사용자일지라도
해당 B팀 사원들의 명단을 조회할 권한은 B팀 사원들 뿐이였고
나는 명단에 접근할 권한을 받지 못해서 Unathorized User로 거부당한 것이다.
회사에게서 403 Forbidden Response를 받고
퇴짜를 맞은셈이 된다.