크롬 익스텐션?
현재 다니는 회사의 출근과 퇴근을 찍을 수 있고 연차신청도 할 수 있는 사내 툴이 있는데 이 사이트가 자동로그인 없어서 너무 불편했다.
하루에 무조건 2번 이상은 들어가는데 자동로그인 기능이 없다는 거에 불편함을 많이 느껴서 개선의 필요성을 느꼈다.
처음에는 사이트에 자동로그인 버튼이 있었다. 체크해도 자동로그인이 되진 않았지만 앞으로 개발 예정이겠거니 생각했는데 언제부턴가 아이디 저장으로 바뀌었고 그 기능은 동작을 한다.
그래서 자동로그인 기능이 앞으로 개발되지 않을 거라고 판단해서 개발을 마음먹었다.
개발 전 어떤식으로 로그인이 진행이 되는지 네트워크 탭을 확인해 봤는데 아이디랑 비밀번호를 넣으면 HTTP 요청을 보내기 전 암호화가 되어서 보내진다.
암호화하는 알고리즘은 내가 알아낼 수 없고 알고리즘을 모른다면 아이디와 비밀번호를 가지고 네트워크 요청을 직접 할 수 없게 된다.
따라서 홈페이지 방문은 필수적이고 버튼의 DOM 엘리먼트를 잡아서 로그인을 진행해야 한다. 추가로 이용의 편의성을 위해 크롬 익스텐션으로 개발하기로 했다.
크롬익스텐션은 처음이야
기본적으로 크롬익스텐션에서 요구하는 Output은 다음과 같다.
├── background.js
├── content.js
├── icon128.png
├── icon16.png
├── icon48.png
├── manifest.json
├── popup.html
├── popup.js
└── popup.js.LICENSE.txt
…
이 중 manifest.json과 background.js, content.js, popup.js에서 설명해 보자면
background.js
크롬 확장 프로그램의 백그라운드 페이지에 대한 스크립트로, 확장 프로그램이 설치되고 나서부터 크롬이 종료될 때까지 계속 실행되는 스크립트. 이 스크립트는 확장 프로그램의 지속적인 상태를 관리하거나, 이벤트 리스닝, 알림 생성, 주기적인 작업 수행 등의 백그라운드 작업에 사용됨.
popup.js
확장 프로그램의 팝업 UI에 대한 스크립트로, 사용자가 확장 프로그램 아이콘을 클릭했을 때 나타나는 팝업 창에 대한 동작을 정의. 팝업 창에 대한 사용자 인터페이스를 제어하고, 사용자의 입력을 처리하는 데 사용됨.
content.js
콘텐츠 스크립트로, 특정 웹 페이지의 컨텍스트 내에서 실행. 이 스크립트는 웹 페이지의 DOM에 접근하여 페이지의 내용을 읽거나 변경할 수 있음. 예를 들어, 페이지에 새로운 요소를 추가하거나, 사용자의 동작을 추적하거나, 웹 페이지의 데이터를 읽는 데 사용됨.
manifest.json (중요)
확장 프로그램의 메타데이터 파일로, 확장 프로그램의 이름, 버전, 권한, 아이콘, 배경 스크립트, 컨텐츠 스크립트 등 확장 프로그램을 구성하는 데 필요한 모든 정보를 정의함. 이 파일은 크롬 확장 프로그램의 필수적인 부분으로, 확장 프로그램의 설정과 기능을 크롬에 알려줌.
정확히 위와 같은 폼으로 그리고 압축된 상태로 제출해야만 한다.
그래서 바닐라 js로 구현을 하려고 했는데
개발 속도가 너무 느려질 거 같아서 react로 앱을 시작한 다음에 웹팩을 커스터마이징 해서 결과적으로 나올 output만 크롬에서 원하는 형식으로 바꿔주도록 환경을 세팅했다.
// webpack.config.js
const webpack = require("webpack");
const path = require("path");
const CopyPlugin = require("copy-webpack-plugin");
const config = {
entry: {
popup: path.join(__dirname, "src/popup.tsx"),
content: path.join(__dirname, "src/content.ts"),
background: path.join(__dirname, "src/background.ts"),
},
output: { path: path.join(__dirname, "dist"), filename: "[name].js" },
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: "babel-loader",
exclude: /node_modules/,
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
exclude: /\.module\.css$/,
},
{
test: /\.ts(x)?$/,
loader: "ts-loader",
exclude: /node_modules/,
},
{
test: /\.css$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 1,
modules: true,
},
},
],
include: /\.module\.css$/,
},
{
test: /\.svg$/,
use: "file-loader",
},
{
test: /\.png$/,
use: [
{
loader: "url-loader",
options: {
mimetype: "image/png",
},
},
],
},
],
},
resolve: {
extensions: [".js", ".jsx", ".tsx", ".ts"],
alias: {
"react-dom": "@hot-loader/react-dom",
},
},
devServer: {
contentBase: "./dist",
},
plugins: [
new CopyPlugin({
patterns: [{ from: "public", to: "." }],
}),
],
};
module.exports = config;
이렇게 세팅하고 package.json의 스크립트에
"scripts": {
"build": "webpack",
"start": "webpack --watch"
},
추가해 주고 "npm run start"를 통해 웹팩을 워치모드로 실행해 준다.
이렇게 하면 저장할 때마다 자동으로 dist파일이 생성이 되어서 즉각적으로 코드반영분을 보면서 개발할 수 있다.
디버깅하는 방법은 다음과 같다.
이제 압축된 파일을 로드하고 언팩 하면 나온다.
update 하면서 개발을 하면 된다.
결과물
참고로 구글 크롬 익스텐션에 등록하는데 5$가 든다,,
추가 11/03
추가 기능 예정
- 팝업에서 홈페이지 바로 이동
- 토글버튼으로 활성화/비활성화
- 팝업에서 출근/퇴근
- 09:30, 18:30 출/퇴근 알림
추가 11/06
두 번의 reject 끝에 드디어 v1 배포완료
추가 11/07
- v1.1.3
- 토글버튼으로 활성화/비활성화
토글버튼으로 특정 사이트에 방문할 때 자동로그인되는 기능을 멈추고 다시 시작할 수 있도록 토글을 구현했다.
// App.tsx
// ... 기존코드
const [autoLoginEnabled, setAutoLoginEnabled] = useState(true);
const toggleAutoLogin = () => {
const newAutoLoginEnabled = !autoLoginEnabled;
setAutoLoginEnabled(newAutoLoginEnabled);
chrome.storage.sync.set({ autoLoginEnabled: newAutoLoginEnabled });
};
useEffect(() => {
chrome.storage.sync.get(["autoLoginEnabled"], (result) => {
// 마운트 시 autoLoginEnabled의 여부 판단
if (result.autoLoginEnabled !== undefined) {
setAutoLoginEnabled(result.autoLoginEnabled);
} else {
setAutoLoginEnabled(true);
chrome.storage.sync.set({ autoLoginEnabled: true });
}
});
}, []);
<div className={`${autoLoginEnabled ? "App" : "App-off"}`}>
<header className="App-header">
<h2 className="App-header-text">SURFING IS FUN</h2>
</header>
<div className="App-body">
<div className="App-option">
//.. 기존코드
<span className="App-toggle" onClick={toggleAutoLogin}>
<span className="App-toggle-wrapper">
<span className="App-toggle-on">ON</span>
<span className="App-toggle-off">OFF</span>
<span
className={`App-toggle-slider ${autoLoginEnabled ? "" : "off"}`}
/>
</span>
</span>
</div>
//.. 기존 코드
{isSaved ? (
<button
onClick={handleEditClick}
className="App-submit"
disabled={!autoLoginEnabled}
>
수정
</button>
) : (
<button
onClick={saveCredentials}
className="App-submit"
disabled={!autoLoginEnabled}
>
저장
</button>
)}
</div>
);
};
export default App;
결과
🟩 팝업에서 홈페이지 바로 이동
🟩 토글버튼으로 활성화/비활성화
🟥 팝업에서 출근/퇴근 (보안상, 업무에 영향을 끼칠 수 있어서 중단)
🟩 09:30, 18:30 출/퇴근 알림
추가 24/06/07
현재 사용인원
'재미' 카테고리의 다른 글
드디어 열린 취업의 문 (3) | 2023.10.17 |
---|---|
뛰는 고양이를 코드로 구현해보자 (5) | 2023.07.29 |
ChatGPT를 이용한 자동화 블로그 (2) | 2023.04.29 |