이전 포스팅에서 AWS lambda와 api gateway를 이용해 rest api를 만들었습니다. 이번에는 해당 api를 바탕으로 초대 링크 생성 및 해당 링크를 입력하였을 때 리다이렉션 되도록 설정해보겠습니다.
포스팅에서 설명하는 코드 이외에는 삭제하였습니다.
import axios from 'axios';
import { useState } from 'react';
import { CopyToClipboard } from 'react-copy-to-clipboard';
import toast from 'react-hot-toast';
import styled from 'styled-components';
import { API } from '../config';
export default function Invite() {
const [isInvited, setIsInvited] = useState(false);
const [inviteCode, setInviteCode] = useState('');
const onClickInviteButton = () => {
const roomId = '123';
axios.get((API.INVITE as string) + roomId).then((res) => {
setIsInvited(true);
setInviteCode(`${process.env.REACT_APP_LAMBDA_INVITE}/${res.data}`);
});
};
return (
...
{!isInvited ? (
<Button type="button" onClick={onClickInviteButton}>
초대하기
</Button>
) : (
<>
...
<CopyToClipboard
text={inviteCode}
onCopy={() => toast.success(`복사되었습니다. ${inviteCode}`)}
>
<Button>복사</Button>
</CopyToClipboard>
...
</>
)}
);
}
const Button = styled.button`
color: white;
font-size: 2rem;
cursor: pointer;
padding: 1rem;
border-radius: 1.4rem;
&:hover {
color: #ffe2e2;
}
`;
초대하기 버튼을 누르면 클릭 이벤트로 onClickInviteButton
함수가 실행됩니다. roomId
는 임시로 123으로 지정하였고 axios를 이용해 get 요청을 하였습니다. 해당 링크로 요청을 보내면 api gateway를 통해 lambda 함수가 실행됩니다. 그러면 roomId
에 대해 암호화를 한 후 response
로 보내주게 됩니다. 해당 로직은 뒤에서 다시 설명드리겠습니다. 이후 setInviteCode
로 초대링크를 설정해줍니다.
클립보드는 react-copy-to-clipboard
라이브러리를 이용하였습니다. onCopy, 즉 복사 버튼을 눌러 inviteCode
가 복사 되었을 때 toast
알람이 나옵니다.
roomId
에 대한 정보를 암호화 하여 보여주기 위해 crypto
라이브러리를 이용하였습니다. lambda에서 외부 라이브러리를 사용하기 위해 layer 설정을 추가로 해주었습니다.
우선 빈 폴더에 아래와 같이 crypto
라이브러리를 설치해줍니다.
npm install crypto-js
그리고 폴더에 있는 node_modules 파일을 nodejs라는 빈 폴더에 붙여넣어 줍니다.
이를 zip 으로 압축하여 다음과 같이 업로드 하여 생성해주었습니다.
const crypto = require('crypto');
...
const encoding = (text) => {
const cipher = crypto.createCipher('aes-256-cbc', KEY);
let encode = cipher.update(text, 'utf8', 'base64');
encode += cipher.final('base64');
return encode;
}
const decoding = (text) => {
const decipher = crypto.createDecipher('aes-256-cbc', KEY);
let decode = decipher.update(text, 'base64', 'utf8');
decode += decipher.final('utf8');
return decode;
}
module.exports = {encoding, decoding}
crypto
라이브러리를 이용해 encoding, decoding 해주는 함수를 작성하였습니다.
...
exports.handler = async (event, context) => {
let encodedRoomId;
let roomToRedirect;
const headers = {
"Content-Type": "application/json"
};
const payload = {
headers,
};
try {
switch (event.routeKey) {
case "초대하기 버튼 눌렀을 때":
encodedRoomId = encoding(event.pathParameters.roomId);
encodedRoomId = encodeURIComponent(encodedRoomId);
payload.statusCode = 200;
payload.body = JSON.stringify(encodedRoomId);
break;
case "사용자가 url을 입력했을 때":
const decodedRoom = decodeURIComponent(event.pathParameters.code);
roomToRedirect = decoding(decodedRoom);
payload.statusCode = 302;
payload.headers = { Location: `${FE_URL}/${INVITION_ROUTE}/${roomToRedirect}` };
break;
...
}
} catch (err) {
payload.statusCode = 400;
payload.body = JSON.stringify(err.message);
}
return payload;
};
초대하기 버튼을 누르면 roomId
를 만들어둔 endcoding
함수를 이용해 암호화 해줍니다. 이렇게 암호화한 roomId
를 encodeURIComponent
를 이용해 ?,=,/,&,: 와 같은 문자를 다른 문자로 인코딩해줍니다.
사용자가 url을 입력했을 때는 decodeURIComponent
과 decoding
함수를 순차적으로 하여 원래 roomId
로 디코딩해줍니다. 또한 statusCode
를 302로 하여 Location
으로 리다이렉션 해줍니다.
이렇게하여 초대링크를 생성하고 해당 링크로 참여할 수 있게 되었습니다👏 다음에는 실제 프로젝트에 적용하여 인증된 사용자인지 확인하기 등 세부 기능을 추가해보겠습니다.