Angular 프론트엔드와 Express 백엔드를 따로 구현하면서 세션 ID(`connect.sid`)가 브라우저에 저장되지 않는 문제는 프론트엔드와 백엔드 간의 CORS(Cross-Origin Resource Sharing) 설정, 쿠키 설정, 또는 세션 관리 방식과 관련이 있을 가능성이 큽니다. 여기서 가장 중요한 점은, 브라우저가 다른 도메인(또는 포트)에서 보내는 쿠키를 기본적으로 허용하지 않는다는 점입니다. 다음은 이 문제를 해결하기 위한 주요 원인과 해결 방법입니다.
### 1. **CORS 설정**
- 프론트엔드와 백엔드가 다른 도메인 또는 포트에서 실행되면, 브라우저는 기본적으로 서로 다른 출처 간의 요청을 차단할 수 있습니다. 이때, 서버에서 CORS 설정을 제대로 해야 쿠키가 정상적으로 전달되고 저장될 수 있습니다.
**해결 방법:**
- Express 서버에서 CORS 설정을 활성화하고, `credentials`를 허용하도록 설정해야 합니다. 예를 들어, `cors` 미들웨어를 사용할 수 있습니다:
- **주의:** `origin`은 Angular 애플리케이션이 실행되는 도메인 또는 포트를 정확히 설정해야 합니다. 이 설정이 없으면 쿠키가 전달되지 않을 수 있습니다.
### 2. **쿠키 설정**
- 쿠키가 브라우저에 저장되지 않는 경우, 서버에서 쿠키 설정에 문제가 있을 수 있습니다. 특히, 쿠키가 `SameSite` 정책에 의해 차단되거나 `Secure` 속성으로 인해 문제가 발생할 수 있습니다.
**해결 방법:**
- Express 세션 설정에서 쿠키 관련 옵션을 설정할 때, `SameSite`와 `Secure` 옵션을 조정해보세요. 예를 들어:
```js
app.use(session({
secret: 'your-secret-key',
resave: false,
saveUninitialized: true,
cookie: {
httpOnly: true, // 클라이언트가 쿠키에 직접 접근하지 않도록 설정
secure: false, // HTTPS가 아닌 경우 false로 설정
sameSite: 'None' // 다른 도메인에서도 쿠키를 허용
}
}));
```
- `secure`는 HTTPS 환경에서만 작동합니다. 만약 로컬 개발 환경이 HTTP라면 `secure: false`로 설정하세요. `sameSite: 'None'`으로 설정하면 쿠키가 다른 도메인에서 요청될 때도 허용됩니다.
### 3. **프론트엔드에서 요청 시 쿠키 전송 설정**
- Angular에서 백엔드로 HTTP 요청을 보낼 때, `withCredentials` 옵션을 사용해 쿠키가 함께 전송되도록 설정해야 합니다. 만약 이 옵션을 누락하면 쿠키가 전달되지 않아 세션이 유지되지 않습니다.
**해결 방법:**
- Angular에서 HTTP 요청 시 `withCredentials: true`를 설정합니다:
### 4. **HTTPS vs HTTP**
- 만약 로컬 개발 환경에서 HTTPS를 사용하지 않는다면, `Secure` 쿠키가 작동하지 않습니다. 이 경우, 쿠키 설정에서 `Secure: false`로 설정해야 합니다. 배포 환경에서는 HTTPS를 사용하도록 설정하는 것이 중요합니다.
### 5. **서버 측에서 세션 ID가 제대로 관리되는지 확인**
- 서버에서 세션 ID를 제대로 생성하고 관리하고 있는지 확인하세요. 서버가 세션 ID를 클라이언트로 전송하고 있는지, 그리고 세션 ID가 요청마다 일관되게 유지되는지 확인해야 합니다.
### 6. **브라우저 개발자 도구 확인**
- 개발자 도구에서 `네트워크` 탭을 열고 요청의 `쿠키`와 `응답 헤더`를 확인하세요. 서버가 제대로 세션 ID를 전달하고 있는지, 그리고 클라이언트가 해당 쿠키를 받아 저장하는지 확인할 수 있습니다.
### 요약
프론트엔드(Angular)와 백엔드(Express)를 분리하여 사용하는 경우, 쿠키 기반 세션을 유지하려면 다음 사항들을 확인해야 합니다:
1. **CORS 설정에서 `credentials: true` 설정**: 서버에서 쿠키가 전송될 수 있도록 허용.
2. **세션 쿠키 설정**: `SameSite`와 `Secure` 옵션을 적절하게 설정.
3. **프론트엔드 요청 시 `withCredentials: true` 사용**: 요청 시 쿠키가 함께 전송되도록 설정.
4. **브라우저 개발자 도구로 네트워크와 쿠키 확인**: 서버에서 제대로 쿠키가 전송되고 있는지, 클라이언트가 그 쿠키를 받고 있는지 확인.
이 방법으로도 문제가 해결되지 않으면 구체적인 코드나 설정을 추가로 공유해주시면 더 구체적으로 도와드릴 수 있습니다.
MySQL에 세션을 저장하고, 브라우저에서 다른 페이지로 이동할 때마다 새로운 세션이 계속 생성되는 현상은 일반적으로 정상적인 동작은 아닙니다. 기본적으로 세션은 사용자가 사이트에 접속할 때 한 번 생성되고, 그 세션이 유지되는 동안에는 동일한 세션을 재사용해야 합니다. 새로운 페이지로 이동할 때마다 세션이 새로 생성된다면, 문제가 발생한 것이므로 다음과 같은 원인과 해결 방법을 고려해볼 수 있습니다.
### 1. **세션 쿠키 문제**
- 세션 ID는 일반적으로 브라우저의 쿠키에 저장되며, 그 세션 ID를 통해 서버는 사용자의 세션을 식별합니다. 만약 브라우저가 세션 쿠키를 저장하지 못하거나, 페이지 이동 시 쿠키가 사라진다면 매번 새로운 세션이 생성될 수 있습니다.
**확인 사항:**
- 브라우저가 쿠키를 제대로 저장하고 있는지 확인합니다.
- 쿠키가 페이지 이동 간에 유지되고 있는지 확인합니다.
- HTTPS 환경에서는 쿠키 설정에 `Secure` 플래그가 잘 설정되어 있는지 확인합니다.
### 2. **세션 타임아웃 설정**
- 세션 타임아웃이 너무 짧게 설정된 경우, 페이지 이동 중에 세션이 만료되고 새로 생성될 수 있습니다. 예를 들어, 페이지 로드 시간 동안 세션이 만료되면 새로운 세션이 시작될 수 있습니다.
**확인 사항:**
- 세션 타임아웃 설정을 확인합니다. PHP의 경우, `php.ini`에서 `session.gc_maxlifetime` 설정을 확인하거나, MySQL에서 세션 유지 시간을 확인해보세요.
### 3. **세션 저장 방식의 문제**
- 세션을 MySQL에 저장할 때, 세션 ID를 관리하는 로직에 문제가 있는 경우에도 새로운 세션이 계속 생성될 수 있습니다. 예를 들어, 세션 ID가 제대로 저장되지 않거나 불러오지 못하는 경우 매번 새로운 세션이 만들어질 수 있습니다.
**확인 사항:**
- 세션이 MySQL에 제대로 저장되고 있는지 확인합니다.
- 세션 저장 시 기존 세션이 제대로 불러와지고 있는지 확인합니다.
- 세션 ID를 생성, 저장, 불러오는 부분의 로직에 문제가 없는지 확인합니다.
### 4. **브라우저 설정 문제**
- 일부 브라우저나 확장 프로그램(예: 보안 확장 프로그램, 광고 차단 프로그램 등)이 세션 쿠키를 차단하거나 삭제할 수 있습니다. 그로 인해 페이지 이동 시마다 새로운 세션이 생성될 수 있습니다.
**확인 사항:**
- 브라우저 설정이나 확장 프로그램이 세션 쿠키를 방해하고 있지 않은지 확인합니다.
- 다른 브라우저나 시크릿 모드를 사용해 동일한 문제가 발생하는지 확인해보세요.
### 5. **PHP 세션 설정 문제**
- PHP에서 세션을 다룰 때, `session_start()` 호출 전에 세션 설정이나 초기화가 올바르게 되어 있지 않다면, 매번 새로운 세션이 생성될 수 있습니다.
**확인 사항:**
- 모든 페이지에서 `session_start()`가 제대로 호출되고 있는지 확인합니다.
- 세션 ID가 페이지 간에 유지되는지 확인합니다 (`session_id()`를 사용해 확인 가능).
### 요약
페이지 이동마다 새로운 세션이 계속 생성되는 것은 정상적인 동작이 아닙니다. 이 문제는 세션 쿠키가 유지되지 않거나, 세션 저장 로직에 문제가 있을 가능성이 큽니다. 다음 사항을 점검하세요:
- 브라우저 쿠키가 정상적으로 저장 및 유지되고 있는지 확인
- 세션 타임아웃 설정 확인
- MySQL에 세션 저장 및 불러오는 로직에 문제가 없는지 점검
- 브라우저 확장 프로그램이나 설정 문제 확인
저도 아랫분들 처럼 여러번 로그인/로그아웃을 해야 정상적으로 처리되는데요.
사실은 그렇지 않습니다. 여러분이 로그인/로그아웃 버튼을 한번 누르면 정상적으로 해당 로직이 처리가 됩니다.
한번 누르시고 새로고침을 해보시면 알 수 있어요..
그런데 새로고침을 하지 않고도 이 문제를 해결할 수 있는 방법이 뭔지 모르겠네요 헤헤
+ 추가..
죄송합니다... 여러분들과 저도 같은 처지였어요ㅠㅠ...
++ 또 추가
이 페이지 mysql 수업에서 해답이 나왔어요.
delete 나 req.session.username = user.username 의 실행이 끝나기 전에 redirect 실행이 이루어 질 수도 있기 때문에 아랫분들께서 여러번 로그인이나 로그아웃을 해도 상태가 변하지 않는 문제가 생기는거였어요
이거는 node.js 가 비동기방식으로 진행되기 때문이겠죠?? 이를 해결하는 방법은요
... app.get('/welcome', (req, res) => {
....
if ( && ){
req.session.username = user.username;
// callback 처리를 해준다. 그러면 위의 statement 가 완전히 실행 되어야 redirect를 실행한다.
req.session.save( () => {
res.redirect('/welcome');
});
}
});
이런식으로 redirect를 콜백함수 안에 넣어두면 로그인/로그아웃 시에 상태변화가 잘 됩니다.
Error: EPERM: operation not permitted, rename 'C:\dev\web_nodejs\ex_cookie\sessions\8N-rtazrkSnCPpBH3ajo1eGQXLw-WHiE.json.1722248377' -> 'C:\dev\web_nodejs\ex_cookie\sessions\8N-rtazrkSnCPpBH3ajo1eGQXLw-WHiE.json'
at Error (native)
제발 이것좀 도와주십쇼 file session 하는중인데 왜 저런에러가 뜨면서 자꾸 로그인을 해도 Welcome만 뜨고 어떨때는 파일에 저장된 session값에 displayName이 들어가긴하는데 대부분 안들어갑니다. 위와같은 에러도 계속 뜨고요. 그리고 로그인이 되어도 계속 welcome창만 뜹니다. 정말 이걸로 반나절 삽질하고 있는데 어떻게 해결방법 없을까요?
여기에 한가지 더해서 TravelDreammer님이 알려주신대로 해서 로그인은 됬는데 로그아웃이 안되더라구요
로그아웃에서도
delete req.session.displayName;
req.session.save(function() {
res.redirect('/welcome');
});
req.session.save()문 넣어주니까 제대로 동작하더군요
제 짧은 생각으로는 저를 포함해서 안됬던 분들은 session 정보를 바꾸고 나서 그게 저장이 안됬던 것 같은데
req.session.save()문으로 명시적으로 저장해주어서 제대로 동작이 됬던 것 아닐까 추측해봅니다
안녕하세요 egoing님. 열혈 수강자중에 한명입니다.
orientDB를 이용한 세션스토어 적용을 하고 웹서버 작동 상태에서 /welcome 페이지로 접속하려고 하는데 자꾸 로딩만 될뿐 페이지로 접속되지 않습니다. 원인을 알수없어 댓글을 남깁니다 파일 상태로 저장하는 세션 스토어 부분에는 잘 작동했는데..
windows 사용자 중에 저와 비슷한 문제가 발생하시는 분 있으실거 같아서 올리게 되었어요!
저의 컴퓨터는 windows 10 Pro, nodejs v4.4.5 LTS 입니다.
첫 번째 문제로 app_session_file.js를 하는 과정에서 ./session 디렉토리에 .json 파일이 재생성되는 문제가 발생했어요.
-> app.use(session({ ... })안 property 중에 store: new FileStore()에서 option을 줄 수 있는데 option으로 path를 잡아주니 해결이 되었어요.
-> store: new FileStore( { path: './sessions/'} ) 라고 해주었습니다.
두 번째 문제로 Error : EPERM: operation not permitted, rename ... 하고 파일이름 뒤에 시간정보 같은게 붙는 파일 명에서 없는 정보의 이름으로 연결 시켜주라는 식의 error가 계속 발생되어 supervisor를 사용했더니 충돌이 자꾸 발생해서 무한 재실행 되었어요.
혹시 그 문제 해결 방법 아시면 알려주세요 저도 session 을 파일로 저장하는 부분에서 로그인을 해도 session data가 변경 되지 않아서(DisplayName 추가 안됨) 계속 Welcome login 창만 뜨고 있습니다.
정보가 맞지 않은 경우 send를 redirect로 바꿔도 결과가 같습니다.
Can't set headers after they are sent.
이라고 console.log에 떠서 검색해보니
로그인의 정보를 받아주는 post에서
정보가 맞으면 redirect가 되고 정보가 맞지 않으면 send로 처리한게 문제였던거 같습니다~
구글리을 해보니까 redirect와 send 는 같이쓰면 안된다고 하는데 send부분을 redirect welcome으로 해주면 되더라구요~ 이게 이유가 맞나 궁금합니다
mysql은 방법으로는 잘 작동이 되는데 sessions 파일로 저장하는 부분을 할 때
sessions파일에 정보.json 파일도 생기고 하는데
로그인을 하면 계속 welcome만 뜹니다~ 세션이 유지가 안되는건가 싶기도하고 그대로 따라했는데 말이죠~!
그리고 그 sessions 폴더에 파일에도 변화가 없습니다. 지우고 다시해도 똑같고 그렇습니다 ㅜㅜ 왜그러는걸까요?
mysql에서 알려주신 req.session.save(function{}) 방법도 써봤지만 로그인이 되질않네요 ㅠㅠ
mysql에 저장하는 것은 되는데 왜 유독 파일 저장형태만 이러는 것일까요? ㅜㅜ
파일부분강좌에서 잠시 보여주셨던 브라우저에서 강제로 session을 삭제했을때에 이슈를 한개 발견했습니다.
위 상황에서 서버의 sessions 폴더에는 기존에 남겨뒀었던 Session Key값이 남겨져 있었습니다.
해당 값은 쓰레기 값일 것 같은데요. 해당 키 값을 정리하는 방법이 있을까요?
덩달아 확인해본 결과 서버의 Key값을 삭제하고 서버를 재 부팅 했을때
클라이언트에서 가지고 있는 sid값이 존재하지 않아서 다시 로그인을 시도하였으나 로그인이 되지 않는 현상이 있습니다. 사용자가 서버요청이 왔을때 존재하지 않는 쿠키일 경우 이를 삭제해주는 코드가 들어가야 하는지요? 이래저래 해보고 싶은데 아직 감을 다 못 잡았네요.