LMS 개선 프로젝트
안녕하세요,저는 숭실대학교를 다니고 있는 학생입니다.
대부분의 대학교에서는 온라인 러닝 시스템이 존재할텐데,
숭실대학교에서는 스마트캠퍼스LMS (Canvas기반 신규 LMS, LearningX(러닝엑스)라고 숭실대는 말하네요)를 이용하고 있습니다
그런데,다들 신규 스마트캠퍼스에 만족하시나요?
학기 초에는 배속재생도 지원하지 않았고,잦은 서버이슈로 인해 내가 왜 등록금을 냈나... 라는 생각을 종종 했던 것 같습니다.
지금이야 많이 개선이 되었지만,여전히 사용성이 좋다라고 말하기는 어렵습니다. (적어도 저한테는)
그러던 중에 결국 시험기간에 LMS를 사용하다가 열을 받아버렸고...그렇게 하라는 시험공부는 안하고,LMS를 어떻게 고쳐 볼 수 있을까라는 고민을 시작으로 크롬 확장프로그램을 만들게 되었습니다.
📌 문제
1. 강의 상세페이지로 이동시, 속도도 느리고 팝업, 새창 혹은 새탭으로 열 수 없습니다.
저는 제가 방문해야하는 페이지들을 전부 새탭으로 열어두고 하나씩 처리하곤 합니다.
하지만 현 LMS의 경우 관련 기능을 전부 제공하지 않습니다
2. 파일을 다운로드만 하면 되는데, 굳이 페이지를 이동해야할까요?
미리미리 공부하시는 분들이라면 모르겠지만,저처럼(..ㅎ) 시험기간에 여러 강의자료를 한번에 다운로드하는 분들이라면 한번쯤 겪어보셨을 문제인데요,1주차 강의자료를 다운받고 다시 목록으로 나오면 강의 토글이 8주차로 다시 이동하게 됩니다.정말 별거 아닌 것 같지만, 내가 어디까지 강의를 다운로드 했는지 기억도 안나고....그냥 페이지 이동 없이 강의 리스트에서 바로 다운 받을 수는 없었을까요.
3. 학습 중 최소 한번은 마주치는 무한로딩.
파일이나 영상을 다운 받으러 강의 상세페이지를 이동하는 경우 무한로딩은 필수로 만나게 됩니다.
그럴경우에는 새로고침이 답인데...
새로고침을 해버리면 강의 목록 페이지로 이동해버리는 아주아주아주아주 화가나는 상황이 발생합니다.
📌 목표
LMS로 받는 스트레스 줄이기 (페이지 이동 최소화하기)
해당 목표를 위해서 다음과 같은 핵심 기능이 들어가야한다고 생각했습니다.
1. 새로고침시 페이지가 이동하지 않도록 하기.
2. 무한로딩시 자동 새로고침 시키기.
3. 강의 수강 페이지를 다수개를 새탭, 새창, 팝업으로 열 수 있도록 하기.
4. 자료 다운로드를 페이지 이동없이 이용하도록 하기.
📌 사전 준비
방법
몇가지 방법이 있었지만,시험기간 이후에 GDSC 숭실에서 세미나 발표가 예정되어있었기 때문에,이왕 프로그램을 개발하는거,세미나에서 해당 프로그램 개발과정을 공유 해야겠다라는 생각이 들었습니다.
나름 이름에 구글이 들어가는 단체인 만큼, 구글을 통해서 개발하고 구글을 통해서 서비스를 배포할 계획을 세웠습니다.
그래서 LMS 시스템을 분석하고 프로그램 개발 진행을 디버깅할 수 있는 툴로 크롬 개발자도구를 활용하고,해당 프로그램을 배포할 플랫폼(?)으로는 크롬 확장프로그램을 선택했습니다.
도구
- 크롬 개발자도구
크롬 개발자도구는 웹 개발자분들에게는 매우 친숙한 프로그램일 것입니다.
너무 많은 기능들이 포함되어 있지만,
저는 해당 프로그램 개발을 위해 요소(Elements), 콘솔(Console), 네트워크(Network) 탭을 주로 사용할 것입니다.
각 탭별로 간단히 소개를 하자면,요소(Elements) 는 웹 페이지의 HTML, CSS의 구조를 전반적으로 확인할 수 있습니다.예를들어, 어떤 버튼이 가지고 있는 클래스 값을 파악할 수도 있으며,display: hidden 등으로 숨겨진 DOM요소도 확인할 수 있습니다 .
콘솔(Console) 은 브라우저 상에서 JS를 직접 실행시킬 수 있으며,DOM을 제어하거나 네트워크 요청등의 작업을 진행할 수 있습니다.
또한 개발시에 프로그램 디버깅 용도로 사용할 수도 있습니다.
네트워크(Network) 탭은 웹 페이지에서 요청하는 모든 네트워크 요청 기록을 확인할 수 있습니다.
예를들어, 블로그 글의 목록을 가져오는데 사용하는 API와 그 API에 어떤 Payload, 헤더를 담아서 보내는지 확인할 수 있습니다.
- 크롬 확장프로그램
크롬 확장프로그램은 사용자가 방문하는 페이지나 크롬과 관련된 부분을 제어하거나 개선할 수 있습니다.대표적인 프로그램으로 VPN, React Developer Tool 등등이 있습니다.
확장프로그램은 Manifest 파일만 잘 이해하고, 활용하면 개발에 어려움은 크게 없을 정도로 매우 편리한 개발 도구입니다.
Manifest 파일은 NPM의 package.json과 비슷하게 프로그램의 권한과 정보를 가지고 있습니다.
background 는 크롬의 백그라운드 환경에서 작동시킬 스크립트입니다.
V3로 업그레이드 되면서 크롬의 Service Worker에서 작동된다고 합니다.
또한 높아진 보안 기준으로 인해 항상 실행되도록 하는 것이 힘들다 글이 많이 있으며,
일반 Script에서 돌리기에는 무거운 로직을 이벤트 기반으로 처리한다 정도로 이해하면 좋을 것 같습니다.
popup 과 관련된 파일들은 전부 사용자가 확장프로그램을 눌렀을때 팝업으로 뜨는 요소들에 대한 내용을 담고 있습니다.
해당 파일에서 background나 contentScript에게 메시지를 보내 특정 로직을 실행할 수도 있으며,옵션 정보를 수정할 수 있도록 하는 기능을 제공할 수 있습니다.
contentScript는 사용자가 방문한 페이지에서 작동시킬 스크립트입니다.
사용자가 방문한 페이지의 DOM을 제어하거나, 네트워크 등의 요청을 통해 원하는 기능을 수행할 수 있습니다.
마지막으로 크롬에서 제공하는 API가 따로 존재하고, 이것을 활용하여 추가적인 제어, 접근도 가능합니다.
📌 원인
그 이유를 파악하고자 개발자도구를 이용하여,LMS의 구조를 파악해봤습니다.
우선 놀랍게도 LMS는 리액트로 개발되어 있었습니다.
그런데 여기서 문제는 학습목록, 강의 페이지 등의 중요한 부분은 전부 iframe으로 감싸져 있었다는 것입니다...
그렇기 때문에 학습자들이 페이지를 이동하지만, URL주소는 변경되지 않았던 것이었습니다.
네이버 카페도 이와 비슷한 구조를 가지고 있습니다.
그래서 페이지를 이동해도 URL이 변경되지 않는 경우가 있습니다.
어떤 이유에서 iframe을 이렇게 사용하는지 정말 모르겠는데,아시는 분이 있다면 댓글 부탁드립니다.
아무쪼록 문제 해결은 생각보다 단순할 것만 같았습니다...
그냥 iframe주소를 팝업으로 열어버리면 대부분의 문제가 해결이 되니깐요.
📌 개발
iframe 주소 가져오기
iframe의 주소를 확인하기 위해 크롬의 개발자도구(network 탭)을 활용하였습니다.
네트워크 탭을 통해 확인한 iframe의 정보는 사진과 같았습니다.
여기서 확인한 iframe의 주소는 하기와 같았습니다.
https://canvas.ssu.ac.kr/learningx/coursebuilder/course/18283/learn/312729/unit/2462010/view?user_id=xxxx&user_login=xxxxxx&user_name=xxxxx&user_email=xxxx&role=1&is_observer=false&locale=ko&mode=default
처음에 보고는 어떻게 해당 정보들을 가져올지 고민이 많았습니다.
중간중간 들어가 있는 변수로 보이는 path들, 그리고 사용자 정보인 것 같은 query들에 대해서요.
그러다 문득, 어차피 elements에 있는 요소 중에 해당 값들이 어딘가에는 있겠지라는 생각이 들어elements 탭에서 command+f 로 변수 하나하나를 검색해봤습니다.
다행히 대부분의 변수들은 hidden 형태로 input form에 정보가 담겨있었습니다.
문제는 물음표 처리되어 있는 부분인데, elements나 기타 어디를 봐도 해당 값을 찾을 수 없었습니다.하지만, 결국에는 저 값들도 서버로 부터 네트워크 통신을 통해 내려받은 값일테니 네트워크 기록을 찾아봤습니다.
네트워크 기록을 살펴보니, 출처를 알 수 없었던 값은 각각 subsection_id, unit_id 값이었습니다.
해당 값들을 얻기 위해 이미 브라우저 어딘가에 저장되어 있을 저 기록을 가져오면 좋겠지만,
저의 지식 수준으로는 그냥 똑같은 네트워크 요청을 보내고 해당 값을 파싱하는 것이 더 효율적이라고 생각했습니다.
LMS의 서버에 나는 이러한 사람인데, 강의 목록에 대한 정보를 줘라고 말하려면, 나는 어떤 사람인지에 대해서 정보를 담아 보내야합니다.
요청 헤더를 살펴보면 LMS는 헤더에 Cookie와 Authorization 값을 실어 보내는 것을 확인 할수 있고, 이것이 나는 어떤 사람인지에 대한 정보를 담고 있습니다.
해당 요청을 위해 다음과 같이 코드를 구성할 수 있습니다.
const fetchWithAuth = async (link) => { const res = await fetch(link, { method: 'GET’, headers: { Cookie: document.cookie, Authorization: 'Bearer ' + getCookie('xn_api_token’), }, }); return res.json(); };
그러면 iframe의 url을 만들기 위한 모든 변수들의 출처는 찾아냈습니다.
팝업 열기
확장
페이지 이동없이 강의 자료를 다운로드 하는 것도 위에서 설명한 방법을 통해 구현이 가능합니다.
하지만, LMS는 끝까지 저를 머리아프게 합니다.교수님께서 강의 자료를 올리는 방법이 아마 여러가지인가 봅니다. 그래서 교수님께서 PDF 파일을 올리시면 해당 pdf 전용 게시판으로 연결이 되고,그냥 일반적인 파일을 올리시면 파일 전용 게시판 연결됩니다.
여기서 문제는 각각 파일링크가 달라서,분기처리를 해줘야한다는 점이고,제가 경험해보지 못한 새로운 형태의 게시판이 존재할 수 있다는 점입니다.
더욱이, 코드 상으로는 이 글이 강의영상인지, PDF파일 게시판인지, 파일 게시판인지 확인할 수 있는 명확한 방법이 없다는 것이었습니다.
강의 옆에 뜨는 아이콘으로 분기처리를 하려고 했으나, 각각의 class이름도 통일되어 있지 않은 것 같아 우선은 작업 순위를 뒤로 미뤘습니다.
무한로딩 해결하기
그리고 가장 화가 나버리는 무한로딩입니다.
프로그램이 완성되고, 주변 친구들에게 가장 반응이 좋았던(?) 기능입니다.
그냥 로딩이 N초 이상 로딩 창이 있으면 새로고침 하는 아주 단순한 기능입니다.
다만 이 기능은 팝업으로 게시판을 열었을때만 작동합니다.
작동법
본래 게시판을 클릭하면 기본 기능을 떼어버리고,
무조건 팝업 창을 열도록 해야하나?라는 고민도 했지만,
그래도 기본 기능과 팝업 창으로 열기 기능을 선택할 수 있도록 하는 것이 좋겠다라는 생각이 들었습니다.
그래서 모든 게시판에 버튼 3개를 달아서 쉽게 사용할 수 있도록 하였습니다.
다만 위에서도 언급한 문제가 있는데, 해당 프로그램이 이 게시판이 어떤 게시판인지 파악할 수 없습니다.
그래서 어떤 게시판이던지 3가지 종류의 버튼이 붙어버립니다.(그냥 클릭해보시고 에러가 뜨면 닫아주시면 됩니다...🫠)
⇒ 23년 현재, 숭실대학교의 100% 대면 전환으로 확장프로그램의 필요가 없어졌습니다..ㅠㅠㅠ 🥲
배포
해당 프로그램의 기능들을 사용하기 위에 항상 코드를 브라우저에서 수기로 실행시키는 것은 굉장히 비효율적일 것입니다.
그래서 제가 작성한 코드들이 상황에 맞춰 작동될 수 있도록 하는 크롬 확장프로그램 을 이용합니다!
앞에서 작성되었듯이 크롬 확장프로그램에서 가장 중요한 것은 manifest.json 입니다.
해당 파일에 어디서는 어떤 스크립트를 실행시키고, 어디에서는 이 스크립트를 실행시켜달라고 정보를 담으면 됩니다.
이렇게 관련 내용을 기록해주고, 코드와 함께 크롬에 업로드 하면 스마트캠퍼스에 방문할때마다 자동으로 버튼이 토글되어 사용할 수 있습니다.