본문 바로가기

react

6. next js 사용자 별 페이지 접근 제어 - HOC

- 참조

https://github.com/vercel/next.js/discussions/10925#discussioncomment-12471

- /hoc/withAuthServerSide.tsx


import { Toast } from "antd-mobile";
import { checkPrime } from "crypto";
import { useRouter } from "next/router";
import React from "react";
import * as AuthManager from '../components/manager/AuthManager'
export interface AccesResultModel {
    canAccess :boolean;
    retUrl : string;
    message : string;
}

function CheckAuth(mode : AuthManager.AuthMode, auth : AuthManager.IAuthManager) : AccesResultModel {
    console.log("mode = " + mode);
    // 기본값 : None 모드에서도 사용
    let result : AccesResultModel = {
        canAccess : true,
        retUrl : "",
        message : ""
    }

    if(mode === AuthManager.AuthMode.None){
        result = { canAccess : false, retUrl : "/", message : "접근이 허용되지 않았습니다." };
        return result;
    }
    if(mode === AuthManager.AuthMode.Normal || mode === AuthManager.AuthMode.Expoert ){
        if(!auth.isLogin){
            result = { canAccess : false, retUrl : "/logon", message : "로그인이 필요합니다." }
            return result;
        }
        if(mode === AuthManager.AuthMode.Expoert && !auth.isExpertLogin ){
            result = { canAccess : false, retUrl : "/logonexpert", message : "Expert 로그인이 필요합니다." }
            return result;
        }
    }            
    return result;
}

export function withAuthServerSideProps(mode : AuthManager.AuthMode, getServerSidePropsFunc?: Function){
    return async (context: any) => {
        console.log("withAuthServerSideProps");
        //console.log(context);
        const authMgr = AuthManager.Get(context);
        let result = CheckAuth(mode, authMgr);
        if(!result.canAccess){
            let redirectUrl = result.retUrl !== "/" ? process.env.NEXT_PUBLIC_URL_AUTH + result.retUrl : result.retUrl
            if(result.retUrl !== "/"){
                let protocol = process.env.NODE_ENV === "development" ? "http://" : "https://";//context.req.protocol;
                let var2 = protocol + context.req.headers.host;
                //console.log("var2 = " + var2 );
               
                let var1= context.resolvedUrl;
                var1= encodeURIComponent(var1);
                //console.log("var1= " + var1);
               
                let queryString = "?var1=" + var1 + "&var2=" + var2
                redirectUrl = redirectUrl + queryString;
            }
            return {
                redirect: {
                  permanent: false,
                  destination: redirectUrl,
                },
                props:{},
              };
        }

        // 변환 : Object -> Json String - > Json Object
        const auth = JSON.parse(JSON.stringify(authMgr));

        if(getServerSidePropsFunc){
            // console.log(" getServerSideProps 가 정의되어 있는 경우 ");
            return {
                props: {
                    auth : auth,
                    access : result,
                    ...((await getServerSidePropsFunc(context, auth)).props || {}),
                }
            }
        }
       
        // console.log(" getServerSideProps 가 정의되지 않는 경우 ");
        return {
            props: {
                auth : auth,
                data: {props: {auth}}
            }
        };
    }
}


- /pages/test/sample/AuthSample.tsx

import { GetServerSideProps } from 'next';
import * as AuthManager from '../../../components/manager/AuthManager';
import Layout from '../../../components/layout/MainLayout'
import { withAuthServerSideProps } from '../../../hoc/withAuthServerSide';

function AuthSample() {
  return (
    <Layout>
      페이지 권한 처리 샘플
    </Layout>
  )
}

export const getServerSideProps : GetServerSideProps = withAuthServerSideProps(AuthManager.AuthMode.Normal ,
  async (context: any, auth: AuthManager.IAuthManager)=>{
    //console.log(context.req.cookies);
    // 서버API 통신 로직 추가
    let result = {"code":1}
    context.req.col
    return {
      props: {
        result,
      },
    }
});
export default AuthSample