Undergrad Research

유저 정보 parsing

Jay_J 2024. 7. 3. 08:18

해야 할 일 : CAS SSO 로그인을 통해 유저를 로그인 시킨 후, 유저의 역할(이번 프로젝트에서는 학생, 교수님 밖에 없다.)에 따라 라우팅 되는 페이지를 달리 설정한다.

 

💡로그인 된 유저가 학생인지, 교수님인지 어떻게 알 수 있을까?

- 맨 처음에는 유저에게 직접 물어볼까 생각을 했다. 유저가 처음 로그인을 하는 상태라면, 학생인지 교수님인지 물어 본 후, 그에따라 라우팅을 하려고 했지만, 만약 악의적인 학생이 교수님으로 설정 후 다른 학생들의 정보를 건드리는건 위험한 일이다. 

 

- 개발을 진행하며 디버깅을 위해 콘솔을 마구 찍어내던것이 생각났다. CAS로그인을 한 후, CAS응답에서 역할을 추출하면 될것 같았다. 그래서 이 방법으로 진행 해 보기로 했다.

 

1. 먼저, backend 디렉토리의 서버.js 파일 안에 유저의 role을 가져오는 함수를 하나 작성 해 준다.

아래가 서버 로그에서 추출한 CAS response이다. 여길 잘 확인해보면 cas:eduPersonAffiliation이라는 항목에 affiliate:student라는 항목이 보인다. 나는 VirginiaTech의 학생이기 때문에 여기 student라고 응답이 뜨고, 교수님의 계정으로 테스트 했을땐 faculty라고 되어 있었다.

function getUserRole(attributes) {
  const primaryAffiliation = attributes['cas:eduPersonPrimaryAffiliation'][0];
  const virginiaTechAffiliation = attributes['cas:virginiaTechAffiliation'];

  if (primaryAffiliation === 'faculty' || (virginiaTechAffiliation && virginiaTechAffiliation.includes('VT-FACULTY'))) {
    return 'professor';
  } else if (primaryAffiliation === 'student' || (virginiaTechAffiliation && virginiaTechAffiliation.includes('VT-STUDENT'))) {
    return 'student';
  }
  return 'unknown';
}

 

이와 같이 getUserRole이라는 함수를 작성 해준다.

 

다음으로, 로그인이 될때 /Dashboard 엔드포인트로 유저를 리디렉션 하므로 /Dashboard에 GET요청을 처리하는 부분에 나머지 처리 로직을 구현 해 준다.

app.get('/Dashboard', async (req, res) => {
		//나머지 부분 생략...
        const user = result['cas:serviceResponse']['cas:authenticationSuccess'][0];
        const pid = user['cas:user'][0];
        const attributes = user['cas:attributes'][0];
        const email = attributes['cas:eduPersonPrincipalName'][0];
        const role = getUserRole(attributes);

        if (role === 'student') {
          console.log("Redirecting to student page....")
          res.redirect('https://crescendo.cs.vt.edu/DashBoard');
        } else if (role === 'professor') {
          console.log("Redirecting to faculty page....")
          res.redirect('https://crescendo.cs.vt.edu/FacultyDashBoard');
        } else {
          res.status(403).send('Access denied');
        }
      });
      //나머지 부분 생략...

});

 

이렇게 하면 교수님은 교수님 전용 페이지로, 학생은 학생 전용 페이지로 이동 할 수 있다.

 

- CAS같은 로그인 프로토콜을 이용한다면, CAS의 응답에서 여러가지 정보를 추출 할 수 있다는것을 기억하자! 이번 프로젝트에서는 CAS응답에서 유저의 역할 뿐만 아니라, 학교 이메일, 이름 등등 여러가지를 가져 올 수 있었다.

 

🔎 TroubleShooting

그런데 자꾸 문제가 발생한다. 이전에는 이런 일이 없었는데 로그인을 하고 일정 시간이 지나면 어디선가 /Dashboard로 요청을 보낸다. 하지만 이 요청은 CAS를 통해 인증된 유저가 아니며, 오류를 발생 시키는데, 이 오류에 대한 처리를 하지 않아 그냥 서버가 종료 되어버린다. 내 서버는 screen을 통해 백그라운드에서 실행중이기 때문에 서버가 끊겨버리면 유저는 아무것도 할 수 없이 페이지가 안 보이는 상황을 마주하게 될 것이다. 다음 포스팅에서는 이 오류에 대해 해결하는 포스팅을 이어가겠다!