728x90

AppleLogin 라이브러리에서 email 정보도 가져와서 사이트에서 활용해야 한다면 responseMode 를 form_post 로 설정하고 값을 보내고 다시 post 로 데이터를 받아야 한다.

 

 

post 데이터를 받는 부분이기 때문에 백엔드로 받아서 front 에서 토큰을 저장하는 로직을 구현 해주어야 한다. 

import React from 'react';
import AppleLogin from 'react-apple-login';

const AppleLoginButton = () => {
  const handleSuccess = (response) => {
    console.log("로그인 성공:", response);
    // 서버에 response.id_token을 보내서 사용자 정보를 처리합니다.
    fetch('https://yourapp.com/api/auth/apple', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        id_token: response.id_token,
      }),
    })
    .then(res => res.json())
    .then(data => {
      console.log("서버 응답:", data);
      // 사용자 정보를 처리합니다.
    })
    .catch(error => {
      console.error("서버 통신 실패:", error);
    });
  };

  const handleError = (error) => {
    console.error("로그인 실패:", error);
  };

  return (
    <AppleLogin
      clientId="com.yourapp.identifier" // 애플 개발자 계정에서 등록한 클라이언트 ID
      redirectURI="https://yourapp.com/auth/apple/callback" // 리다이렉트 URI
      responseType="id_token" // id_token으로 변경
      responseMode="form_post" // POST 방식으로 변경
      usePopup={true} // 팝업으로 로그인할지 여부
      onSuccess={handleSuccess}
      onError={handleError}
    />
  );
};

export default AppleLoginButton;

 

이때 redirectURI 는 백엔드 api url 을 주어야 하고 아래와 같이 백엔드에서는 post 로 받아서 다시 front 로 /front/login 으로 id 와 email 정보를 넘겨 주고 front 에서는 세션 처리를 하면 된다.

email 값이 안넘어 온다면 form_post 로 변경해 보길 권한다. 

const appleToken = async (request, response) => {
    const { code } = request.body;

    if (!code) {
        return response.status(400).json({ message: 'Code is required.' });
    }

    const result = (data, message) => {
        if (message === messageMap.OK) {
            const { id, email } = data;
            response.redirect(`https://프런트도메인/front/login?snsid=${id}&email=${email}`);
        } else {
            response.status(message.status).json({ message: message.string });
        }
    };
};
728x90
728x90

1.애플 개발자 계정 설정

먼저, 애플개발자계정에서 앱을 등록하고,"SigninwithApple"기능을 활성화 해야합니다.이 과정에서 BundleID와 관련된 설정을 하게 됩니다.

 

2.필요한 라이브러리 설치

리액트에서 애플로그인을 쉽게구현하기 위해react-apple-login같은 라이브러리를 사용할수 있습니다.다음과 같이 설치합니다.

npm install react-apple-login

 

3. 로그인 버튼 구현

애플로그인에서 AppleLogin 라이브러리를 사용한다면 한가지 유의할 점이 있다. 아래와 같이 responseMode 를 query 보내게 되면 이메일 계정 정보를 선택하는 화면이 노출 되지 않는다. 단순히 애플 로그인만 사용 할수 있으니 이메일정보를 받아와야 하는 프로젝트라면 post 방식을 이용해야 한다. 

import React from 'react';
import AppleLogin from 'react-apple-login';

const AppleLoginButton = () => {
  const handleSuccess = (response) => {
    console.log("로그인 성공:", response);
    // 서버에 response를 보내서 사용자 정보를 처리합니다.
  };

  const handleError = (error) => {
    console.error("로그인 실패:", error);
  };

  return (
    <AppleLogin
      clientId="com.yourapp.identifier" // 애플 개발자 계정에서 등록한 클라이언트 ID
      redirectURI="https://yourapp.com/auth/apple/callback" // 리다이렉트 URI
      responseType="code"
      responseMode="query"
      usePopup={true} // 팝업으로 로그인할지 여부
      onSuccess={handleSuccess}
      onError={handleError}
    />
  );
};

export default AppleLoginButton;

 

4. 서버 백엔드 처리

애플 로그인 후, 받은 인증 코드를 서버로 전송하여 사용자 정보를 가져오는 과정이 필요합니다. 서버에서는 애플의 API를 호출하여 사용자 정보를 검증하고, 필요한 경우 데이터베이스에 저장합니다.

 

5. 애플 로그인 api 예시 (Node.js)

const axios = require('axios');

const verifyAppleToken = async (token) => {
  const response = await axios.post('https://appleid.apple.com/auth/token', {
    // 필요한 파라미터 추가
  });
  return response.data;
};

 

728x90
728x90

리액트에서 페이지 로드 후 바로 실행하기 위해서는 useEffect 에 정의해 준다. vue나 일반적인 javascript 라면 mouted, ready 에 선언해야 할 부분을리액트에서는 useEffect 로 함수마다 정의해도 되고 함수를모아서 호출하는 방식도 가능하다. 

 

아래 예시는 api 호출 후 바로 버튼을 숨김처리 하는 예시다. 사용자 입장에서는 화면에 진입했을때 api 호출 후 나오는 부분이라 페이지에서 바로 확인이 가능하다.   

import React, { useEffect, useState, useCallback } from 'react';

const YourComponent = () => {
  const [isButtonDisabled, setIsButtonDisabled] = useState(true); 

  const user_seq = 'your_user_seq'; // 사용자 시퀀스
  const cont_seq = 'your_cont_seq'; // 콘텐츠 시퀀스

  const checkUserPlay = useCallback(() => {
    get(`/content/userAgeChk?user_seq=${user_seq}`)
      .then((response) => {
        if (response.messageCode === 200) {
          const { cnt } = response.data;
          if (cnt > 0) {
          	setModalReview(true);
          } else {
          	setModalCheck(true);
          }
        }
      })
      .catch((error) => console.error(error));
  }, [user_seq, cont_seq]); // 의존성 배열에 필요한 값 추가

  useEffect(() => {
    checkUserPlay();
  }, [checkUserPlay]); // 의존성 배열에 checkUserPlay 추가

  return (
    <div>
      <button disabled={isButtonDisabled}>버튼 텍스트</button> 
    </div>
  );
};

export default YourComponent;

 

728x90
728x90

체크박스 전체선택과 일부 선택하면 해제 되는 스크립트는 의외로 꽤 많은 곳에서 사용 되어 진다. 회원가입 약관동의가 대표적이고 리스트중 하나 하나 선택하는 체크박스에도 사용 된다.

  const [checkboxes, setCheckboxes] = useState({
    option1: false,
    option2: false,
    option3: false,
  });

  // 전체 체크박스가 변경되었을 때 나머지 체크박스들을 모두 체크하거나 해제
  const handleAllCheckboxChange = (event) => {
    const isChecked = event.target.checked;
    setAllChecked(isChecked);
    setCheckboxes({
      option1: isChecked,
      option2: isChecked,
      option3: isChecked,
    });
  };
  
  // 개별 체크박스가 변경되었을 때 상태 업데이트 및 전체 체크 상태 업데이트
  const handleCheckboxChange = (event) => {
    const { name, checked } = event.target;
    setCheckboxes((prevCheckboxes) => {
      const updatedCheckboxes = {
        ...prevCheckboxes,
        [name]: checked,
      };
      // 개별 체크박스가 모두 체크된 경우 전체 체크박스를 true로 설정
      const allCheckedStatus = Object.values(updatedCheckboxes).every(Boolean);
      setAllChecked(allCheckedStatus);
      return updatedCheckboxes;
    });
  };

 

선언 부분과 실제 태그를 아래에 메모해 본다. 

<article className="all">
    <input
      type="checkbox"
      className="com_chk"
      id="all"
      checked={allChecked}
      onChange={handleAllCheckboxChange}
    />
    <label htmlFor="all">전체동의 </label>
  </article>
  <ul className="list">
    <li className="item">
      <div>
        <input
          type="checkbox"
          className="com_chk"
          id="agree01"
          name="option1"
          checked={checkboxes.option1}
          onChange={handleCheckboxChange}
        />
        <label htmlFor="agree01">
          전자금융거래 기본약관{' '}
          <span className="txt_required">(필수)</span>
        </label>
      </div>
      <button className="com_btn txt">자세히</button>
    </li>
   </ul>

 

 

728x90

+ Recent posts