React | Next.js 환경에서 나이스(PASS) 신원인증 구현하기
나이스에서 제공하는 개발 가이드에 있는 내용은 보안상 백엔드, 서버에서 처리하는 것이라 생각하시면 됩니다.
프론트에서는 서버에서 나이스에게 요청하여 발급받은 암호화 토큰을 가지고 신원인증 창을 열어주고,
사용자가 신원인증을 완료하고 난 후 받은 데이터를 서버에 주어 서버에서 해당 정보를 복호화하여 유저의 신원인증 정보를 얻을 수 있습니다.
자 그럼 프론트에서 할 일은 암호화 토큰을 요청하여 나이스 인증창을 띄어주고, 유저가 성공하고 리턴받은 토큰을 다시 백에 전달해주면 됩니다. 그래서 저는 신원인증에 사용할 빈 페이지 두개를 만들었습니다.
1. auth page: 서버(나이스)에서 전달받은 토큰을 가지고 나이스 폼 제출하여 본인인증(pass) 창을 띄어주는 페이지
2. complete page : 본인인증 완료했을 때 토큰을 전달하고 여러 후 처리를 위한 페이지 (return page)
나이스 폼을 제출할 페이지로 팝업 띄우기 |
서버에 요청하여 나이스 폼에 제출할 데이터 받아오기 |
나이스에서 제공하는 폼 형식으로 데이터 제출하기 |
나이스 인증 완료 |
return url 로 지정한 페이지에서 nice에서 완료하여 받은 데이터 서버에 전달. |
1. 나이스 폼을 제출할 페이지로 팝업 띄우기
나이스 신원인증 창을 띄우기 위해서는, 나이스 측에서 지정한 폼에 필요 데이터를 연결해주어야 합니다.
본인인증 버튼을 눌렀을 때 팝업창 형식으로 auth 페이지 이동
window.open(`/auth`, '_blank', 'width=400,height=400');
2. 서버에 요청하여 나이스 폼에 제출할 데이터 받아오기 & 나이스에서 제공하는 폼 형식으로 데이터 제출하기
getServerSideProps안에서 유저의 userId 값과 returnUrl 주소를 서버에 전달하고,
응답값으로 nice 폼에 제출할 토큰 정보들을 받아 폼을 제출합니다.
❗️ returnUrl 은 프론트 주소로 해야합니다!
테스트 할 때, 로컬호스트 주소 그대로 적으면 신원인증은 정상적으로 되지만, localhost로 return이 제대로 안될 수 있습니다. 배포를 하여 도메인 주소로 변경하거나, ip주소로 변경하면 로컬에서도 테스트가 가능합니다.
// pages/auth.tsx
export const getServerSideProps: GetServerSideProps<AuthNicePageProps> = async (props) => {
const authQuery = {
userId,
returnurl: `http://192.168.00.000:3000/auth/complete`
}
// api: 요청
const auth = (await UserService.getAuthNiceData(authQuery)).body ?? {};
return {
props: {
auth
}
};
};
const AuthNicePage = ({ auth }: AuthNicePageProps) => {
useEffect(() => {
const myForm = document.getElementById('myForm') as HTMLFormElement;
if (myForm) {
myForm.submit();
}
}, []);
return (
<div>
<form id="myForm" action="https://nice.checkplus.co.kr/CheckPlusSafeModel/service.cb">
<input type="hidden" id="m" name="m" value="service" />
<input type="hidden" id="token_version_id" name="token_version_id" value={auth.tokenVersionId} />
<input type="hidden" id="enc_data" name="enc_data" value={auth.encData} />
<input type="hidden" id="integrity_value" name="integrity_value" value={auth.integrityValue} />
</form>
</div>
);
};
export default AuthNicePage;
3. return url 로 지정한 페이지에서 본인인증 완료하여 nice에서 받은 데이터 서버에 전달.
서버에 return url로 전달하는 이유는, 본인인증을 완료하면 nice측에서 return url로 복호화할 수 있도록 토큰값을 전달해주기 위함입니다.
토큰값을 서버에 전달하면, 서버에서는 해당 토큰값이 유효한 값인지 유저의 데이터와 비교하여 성공, 실패를 다시 판단하여 결과값을 줄것입니다.
그러면 프론트에서는 파라미터를 전달하여 본인인증 창을 띄운 부모창을 새로고침해줍니다.
// pages/auth/complete.tsx
export const getServerSideProps: GetServerSideProps<AuthNiceCompletePageProps> = async (props) => {
const token_version_id = props.query.token_version_id ?? '';
const enc_data = props.query.enc_data ?? '';
const integrity_value = props.query.integrity_value ?? '';
const authQuery = {
token_version_id,
enc_data,
integrity_value
};
// api 요청
const auth = (await UserService.GetAuthNiceReceiveData(authQuery)).body ?? {};
return {
props: {
auth
}
};
};
const AuthNiceCompletePage = ({ auth }: AuthNiceCompletePageProps) => {
useEffect(() => {
const pathname = opener?.location?.pathname;
// 본인인증 완료 후 성공 & 실패 팝업을 띄우기 위한 쿼리 파라미터 설정
const queryString = `?isAuth=${!auth.isSuccess? '0' : '1'}${
auth.systemMessage ? `&msg=${auth.systemMessage}` : ''
}`;
if (window.opener) {
window.opener.location.href = `${pathname}${queryString}`;
}
window.close();
}, []);
return <div />;
};
export default AuthNiceCompletePage;
나이스 제품별 개발가이드는 아래에서 확인할 수 있습니다.
https://www.niceapi.co.kr/#/apis?ctgrCd=0100
나이스평가정보 API-M
나이스평가정보
www.niceapi.co.kr