세션 : 서버에 저장
쿠키 : 브라우저에 저장
세션은 서버가 생성하여 클라이언트에 sid라는 세션 아이디를 전송한다.
세션은 유저 정보같은 민감한 정보를 가지고 있으므로 키가 되는 sid만 클라이언트에 전송하여 보안을 강화한것이다.
클라이언트가 서버로 요청을 보낼때 서버는 이 sid 쿠키로부터 사용자의 로그인 상태등을 유지할 수 있다.
express에서는 express-session을 사용해 세션을 관리할 수 있다.
req.session.user = result.user;
await this.sessionStore.saveSession(req);
user라는 키에 유저 정보를 저장하고, session을 저장했다.
export class SessionStore implements ISessionStore {
async saveSession(req: Request): Promise<void> {
return new Promise<void>((resolve, reject) => {
req.session.save((err) => {
if (err) {
reject(err);
} else {
resolve();
}
});
});
}
session data가 변경되면 자동으로 저장이 되므로
req.session.save로 직접 저장하지 않아도 괜찮다.
보통 로그아웃을 하면 세션을 삭제해 로그인 유지를 푼다.
req.session.destroy()
destroy함수를 통해 세션을 제거할 수 있다.
나는 redis에 세션을 저장하고 있어서 redis에서 세션을 제거했다.
public logout: AsyncRequestHandler = async (req, res) => {
await RedisHandler.findSession(req.body.sessionID);
...생략
await RedisHandler.deleteSession(req.body.sessionID);
static async deleteSession(key: string): Promise<void> {
const sessionKey = `${RedisHandler.SESSION_PREFIX}${key}`;
await redisClient.del(sessionKey);
}
세션 옵션에는 다음과 같은 것이 있다.
export const sessionConfig = {
store: new RedisStore({
client: redisClient,
ttl: REDIS_TIME_TO_LIVE,
prefix: "session:",
}),
cookie: {
httpOnly: true, // 자바스크립트를 통해 세션 쿠키를 사용할 수 없도록 함 localhost, ip일때는 쓰면 안된다. 저장안됨
sameSite: "none",
secure: true,
domain: ".acoha.store",
},
credentials: true,
secret: SESSION_SECRET,
resave: false, //true -> 모든 요청마다 세션을 다시 저장한다.
saveUninitialized: false,//세션에 저장할 내용이 없으면 저장하지 않음
} as SessionOptions;
세션을 어디에 저장할 것인지 명시한다.
나는 redis에 저장했고,
ttl은 세션의 유지 시간이다.
prefix를 통해 저장된 정보가 session임을 알 수 있도록 설정했다.
sid에 대한 설정이다.
디폴트는 다음과 같다.
{ path: '/', httpOnly: false, secure: false, maxAge: null }
cors는 보안상 정책으로 동일 출처인 경우에만 요청이 가능하게 하는 것이다.
다른 출처도 접근을 허용하기위해선 cors 옵션에 허용할 도메인을 명시해주어야한다.
이때 같은 보안상의 이유로 쿠키도 요청을 막고있다.
쿠키를 허용해주기 위해서 서버와 클라이언트 모두 credentials을 true로 해주어야한다.