본문 바로가기

React

[React] 인증

Authentication tokens

사용자가 인증받은 다음 서버에는 이 토큰을 생성하고 그것을 클라이언트에게 전송

토큰(알고리즘에 따라 생성된 스트링으로 몇가지 정보를 담고 있음)

 

토큰을 생성한 백엔드만이 해당 토큰의 유효성을 확인하고 검증 가능

백엔드만이 알 수 있는 개인키를 활용해 토큰 생성

클라이언트가 백엔드에 요청을 보낼 때 해당 토큰을 요청에 첨부하면 백엔드는 토큰을 살펴보고

검증하고 또 그 토큰이 그 백엔드에서 만들어진건지 확인 > 유효한 토큰이면 접근 승인

 

1. 로그인 시

function login(){
	
    const response =  await fetch('로그인 요청 주소및 코드..');
    // 서버에 로그인 요청 코드...
    
    const resData = await response.json();
    const token = resData.token;
    
    localStorage.setItem('token',token);
    // 만료일 설정
    const expiration = new Date();
    expiration.setHours(expiration.getHours() +1);
    localStorage.setItem('expiration',expiration.toISOString());
    
    
    
    

}

> 서버로부터 생성된 토큰을 받아 locaStorage에 저장

 

2. 저장된 토큰을 서버로 넘길 시

export async function action({params, request}){
	const token = localStorage.getItem('token');
    const response = await fetch('주소',{
    	method: request.method,
        headers: {
        	'Content-Type' : 'application/json',
        	'Authorization' :'Bearer ' + token
        }
    
    });

}

서버에 요청할 때, header에 Authoriztion을 넘겨준다. 

 

 

 

3. 로그아웃 시

export function action(){

	localStorage.removeItem('token');
    return redirect('/');
}

> localStorage에 저장된 토큰을 삭제한다.

 

4. 페이지 내에서 로그인이 되었는지 확인 시

- 페이지 컴포넌트

function TestComponent(){
	const token = useRouteLoaderData('root');
    
    return <>
    	{token&& <p>로그인상태</p>}
    </>
}

> useRouterLoaderData를 통해 라우터에서 설정한 loader와 해당 id를 가져와서 token을 조회

 

- 라우터 컴포넌트

const router = createBrowserRouter([
	{
    	path: '/',
        element: <RootLayout />, 
        errorElement: <ErrorPage />,
        id:'root',
        loader: getAuthToken,
        children:[
        	// 자식 라우터...
        
        ]
    }
    
    
    
    
    }



]);

loader에 토큰을 가져오는 함수를 지정해주고 id를 지정하면 자식 라우터에서도 부모 라우터의 loader를 사용할 수 있다.

 

 

5. 새 게시글 이나 게시글 수정과 같이 회원만 접근 가능한 페이지 일 때 (수동으로 주소를 입력해서 들어가는 것을 방지)

 

export function checkAuthLoader() {
  
  const token = getAuthToken();
  
  if (!token) {
    return redirect('/auth');
  }
  
 
  return null; 
}

 // 토큰 만료 유효 기간
  export function getTokenDuration(){
  	const storedExpirationDate = localStorage.getItem('expiration');
    const expirationDate = new Date(storedExpirationDate);
    const now = new Date();
    const duration = expirationDate.getTime() - now.getTime();
    return duration;
    
  
  }
  
  export function getAuthToken(){
  	const token = localStorage.getItem('token');
    
    const tokenDuration = getTokenDuration();
    
    if(!token){
    	return;
    }
    
    
    if(tokenDuration < 0){
    	return 'EXPIRED';
    }
    return token;
  
  }

> 새 게시글 등록 페이지, 게시글 수정 페이지 라우터의 loader에 token이 없으면 다른 페이지로 redirect하는 코드를 넣어준다.

 

 

6. 자동 로그아웃

 

function RootLayout(){
	const token = useLoaderData();
    const submit = useSubmit();
    
    useEffect(() =>{
    	if(!token){
        	return;
        
        }
        
        const tokenDuration = getTokenDuration(); 
        
        
        setTimeout(()=>{
       	 submit(null,{action: "/logout",method: 'post'});
        },tokenDuration);
    
    },[token, submit]);



}

'React' 카테고리의 다른 글

[React] Tanstack 쿼리 , POST  (0) 2024.05.14
[React] Tanstack 쿼리  (0) 2024.05.10
[React] Router , action, defer()  (0) 2024.04.30
[React] router loader, useNavigation  (0) 2024.04.24
[React] router  (0) 2024.04.23