둘다 비슷..
프로미스화 (promisify)
https://medium.com/harrythegreat/node-promisify%EB%A1%9C-promise-%EC%89%BD%EA%B2%8C-%EB%A7%8C%EB%93%A4%EA%B2%8C-27e58a211cf2
환경변수...? secret
https://poiemaweb.com/nodejs-keeping-secrets
https://0strich.tistory.com/39
파일 분리 안하고 하는 방식
https://wildeveloperetrain.tistory.com/21
redis란 무엇인가
https://velog.io/@ohzzi/Access-Token%EA%B3%BC-Refresh-Token%EC%9D%84-%EC%96%B4%EB%94%94%EC%97%90-%EC%A0%80%EC%9E%A5%ED%95%B4%EC%95%BC-%ED%95%A0%EA%B9%8C
refresh token을 어디에 저장할지...
redis말고 쿠키로 하자
이유1. redis는 windows 버전을 지원하지 않아서 깃허브로 받는데.. 이게 공식적인게 맞는지? 최근 업데이트가 2016년임 뭔가 .. 찝찝
이유2. 환경 변수 설정에.. 포트 설정에... 사실 좀 귀찮은것도 있고 ㅎㅎ
https://security.stackexchange.com/questions/194774/how-to-handle-refresh-tokens
refresh token을 어디에 저장할지...2
https://goodteacher.tistory.com/97
https://velopert.com/?s=jwt
최종
https://pamyferret.tistory.com/9
redis 설치
exe파일 안눌러도 작업관리자 열어보면 서비스에 깔려있음
cli파일로 연결 확인
https://www.bezkoder.com/node-express-vue-jwt-auth/
뷰+express
https://github.com/bezkoder/vue-3-authentication-jwt/tree/master/src
소스코드
https://minu0807.tistory.com/64
뷰에서 jwt 구현
https://www.youtube.com/watch?v=E7INRhMTsX0
지금까지 중에 젤 알아듣기 쉬움... 익스프레스에서 레디스에 리프레시 토큰 저장하고 불러오는것

/auth 로 접속했을때 auth.js가 먼저 실행됨
그래서 req로 값을 넣어준것(res가 아니라)
사용자가 로그인한다.
(VUE)Login.Page.vue에서 handleLogin함수가 실행되면서 로그인 성공(status==200)했을때
store.dispatch("login", data); 해서 isLogin값을 true로 변경한다.
이후
main.js에서
beforeCreate() {
this.$store.dispatch('getMemberInfo') //페이지 새로고침시 vuex의 getMemberInfo Action을 불러서 로그인 상태 및 유저정보를 유지, 리턴한다.
}
로 사용자가 페이지 새로고침시마다 토큰을 검증하고 islogin값을 관리한다.
위 로직이 돌면 스토어에서 아래 로직이 돌면서 express의 user.js의 auth로직이 돌면서
const { auth } = require("../middleware/auth");
먼저 user.js에 router.get("/auth", auth~~)에서 받아서
middleware/auth.js가 실행됨.
auth.js에서는
req.cookies.token으로 현재 토큰값을 받아와서
usermodel.js의 findByToken함수를 실행시켜서 검증을 함
검증이 완료되면 user.js의 /auth로 받은부분에서 유저한테 json데이터를 리턴해줌.
이 데이터로 사용자 정보 값을 활용함.
auth로직으로 토큰 재검증을하고 성공하면 islogin을 true로 갱신함.
getMemberInfo({ commit }) {
//페이지 새로고침시 토큰 유효성 확인
const headers = { "Content-Type": "application/json" }
axios.get(`/api/user/auth`, { headers })
.then(response =>{
if(response.data.isAuth !== false){
commit("loginSuccess", response.data)
}
})
갱신된 islogin값을 vue에서 아래처럼 가져와서
state.isLogin = computed(() => store.state.isLogin);
v-if=isLogin==true 이런식으로 사용함.
또는 리뷰쓰기의 경우 뷰에 routes/index.js에서
라우트 실행전에
{
path: '/bakeryreviewwrite',
component: BakeryReviewWrite,
beforeEnter: loginCheck //라우터 실행 전 이 함수를 먼저 실행하여 리뷰작성시 로그인 유무 확인
},
const loginCheck = (to,from,next) => {
if(isLogin.value === false){
alert('로그인이 필요한 기능입니다.');
next("/login");
} else{
next();
}
}
이런식으로 체크해서 작성가능하게 했음.
https://joshua1988.github.io/web-development/vuejs/vue-router-navigation-guards/
네비게이션가드
refresh token에 유저 정보를 하나도 담지 않으면 access token 발급 받을수 없음...
그럼 refresh와 access token의 유일한 차이점은 만료 시간 뿐인가?
원래라면 refresh를 db에 저장했겠지만.. 지금은 그것도 아님
verify하고 나면 access에는 사용자의 정보를 넣어준다
기본적으로 제공하는 email과 isAdmin외에도 나이, 성별,, 이런것들.. 비밀번호는 아님!
그럼 access token이 가지는 정보가 훨씬 많아지므로... 빠르게 만료 시켜야 하겠지 이런차이....
아님. access token에 정보를 담는순간 탈취당하면 피해가 더 커지니까 안전상의 문제로 이런건 토큰에 안담음...
refresh는 access 발급용, access는 사용자가 누구인지, 권한이 무엇인지 정도만...
마이페이지에서 정보를 수정하는 경우... 그러니까 사용자의 나머지 정보가 필요한 경우에 access token으로
사용자를 구분하고 정보를 바로 받아오는것.. 어디에 담는게 아니다.

jwt로 access, refresh token 생성후 access는 email로 user를 찾아서 isAdmin값을 담은 후 쿠키로 보내서 브라우저에 저장, refresh는 email값만 가지고 access token 만료시 access token 재발급, refresh token도 만료시 로그인 화면이 뜨도록 구현 하였는데..
수많은 고비가 있었지만 가장 마지막에 있었던 고비는 access token과 refresh token에 같은값(email, isAdmin)을 저장하면 따로 생성하는 의미가 없다고 느꼈으므로 isAdmin값은 access token에만 담고 싶었다. 그래서 email값만을 매개변수로 받은뒤 findOne을 이용해서 모델에서 isAdmin값을 찾았는데 findOne 함수에는 async/await를 붙여서 isAdmin값을 찾아옴. 그런데 이렇게 받아온 email과 isAdmin값을 jwt.sign에 넣어주니 Promise를 받아오는것이다... pending 상태란 함수를 진행시키기도 전에 값을 받아온것이라는데...
나는 당연히 findOne의 소행일꺼라 생각했음. 왜냐면 jwt.sign을 하는 곳에서 auth로 따로 빼낸 모듈에서 findOne으로 user를 찾고, 거기에서 jwt.sign을 return하도록 했으니까. 그래서 jwt.sign을 promisify를 이용해서 await를 붙이고 난리였는데.. 그럴 필요가 없었음. 애초에 jwt.sign이 비동기 함수이고...
return하는데 까지는 아무런 문제가 없었던 것이다. 콘솔에서 억세스 만들어졌니에 제대로 찍히는걸 보고 깜짝 놀람....
문제는 jwt.sign을 처음 시작한곳 그러니까 따로 빼낸 auth 모듈이 돌고나서 값이 반환되는 곳에서 값을 받기 전에 출력했다는건ㄴ데 왜인지 모르겠는데 여기에서는 promisify를 따로 안해줘도 await가 그냥 붙더라..? 애초에 이렇게 따로 빼낸걸 다시 받아와야하니까 붙는건지... 아무튼 허망하게도 await 붙이니 해결됨.