티스토리 뷰

안녕하세요 강정호입니다.

 

오늘은 인증을 확인하는 기능을 개발하겠습니다.

 

[화면]

 

Confirm.js

import React from "react";
import styled from "styled-components";
import { TouchableWithoutFeedback, Keyboard } from "react-native";
import { TouchableOpacity } from "react-native-gesture-handler";
import AuthButton from "../../components/AuthButton";
import AuthInput from "../../components/AuthInput";
import { useState } from "react";
import useInput from "../../hooks/useInput";
import { Alert } from "react-native";
import { LOG_IN, CONFIRM_SECRET } from "./AuthQueries";
import { useMutation } from "react-apollo-hooks";
import { useLogIn } from "../../AuthContext";

/** View 컴포넌트의 스타일 지정 */
const View = styled.View`
    justify-content: center;
    align-items: center;
    flex: 1
`;

const Text = styled.Text`

`;

export default ({route, navigation}) => {
    const confirmInput = useInput("");
    const [loading, setLoading] = useState(false);

    /** confirmSecret 호출 : secret, email을 파라메터로 전송 
     * secret : 사용자가 입력한 secret 값을 사용
     * email : Login.js 화면에서 넘겨준 email을 route 컴포넌트에서 받아온다.
    */
    const [confirmSecretMutation] = useMutation(CONFIRM_SECRET, {
        variables: {
            sercret: confirmInput.value,
            email: route.params.email
        }
    });


    /** Confirm 버튼 클릭시 호출
     * 기능 : 입력받은 secret을 검증 한 후 서버의 confirmSecret을 호출하고 token을 받아온다.
     */
    const handleConfirm = async () => {
        const { value } = confirmInput;
        
        if(value === "" || !value.includes(" ")){
            Alert.alert("Invalid secret");
        }

        try{
            setLoading(true);
            console.log("check type under");
            console.log(typeof value);
            const  {
                data: {confirmSecret}
            } = await confirmSecretMutation();

            if(confirmSecret !== "" || confirmSecret !== false ){
                useLogIn(confirmSecret);
            }else{
                Alert.alert("Wrong Secret!");
            }

        }catch(e){
            console.log(e);
            Alert.alert("Can't confirm secret");
        }finally{
            setLoading(false);
        }
    }

    return(
        <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
            <View>
                <AuthInput 
                        {...confirmInput} 
                        placeholder="Secret" 
                        returnKeyType="send"
                        onSubmitEditing={handleConfirm}
                        autoCorrect={false} />
                <AuthButton onPress={handleConfirm} text="Confirm" loading={loading} />
            </View>
        </TouchableWithoutFeedback>
    )
    
};

1. Secret 코드 입력 : 입력란에 secret 코드를 입력하고 Confirm 버튼을 클릭한다.

2. confirmSecret 호출 : Login 화면에서 받아온 email과 입력받은 Secret 코드를 가지고 confirmSecret을 호출한다.

3. 토큰 생성 : confirmSecret의 반환값은 인증 토큰이다. 토큰을 받아서 useLogIn 함수 호출

4. AsyncStorage에 토큰 저장 : 토큰을 저장한다.

 

 AuthQueries.js

import { gql } from "apollo-boost";

export const LOG_IN = gql`
    mutation requestSecret($email: String!){
        requestSecret(email: $email)
    }
`;

export const CONFIRM_SECRET = gql`
    mutation confirmSecret($secret: String!, $email: String!){
        confirmSecret(secret: $secret, email: $email)
    }
`;

 

AuthContext.js

import React, { createContext, useContext, useState } from "react";
import AsyncStorage from "@react-native-async-storage/async-storage";


export const AuthContext = createContext();

export const AuthProvider = ({isLoggedIn: isLoggedInProp, children}) => {

    const [isLoggedIn, setIsLoggedIn] = useState(isLoggedInProp);

    /** logUserIn 함수 호출 : AsyncStorage에 로그인 여부 true 세팅, hook으로 로그인 여부 true 세팅 */
    const logUserIn = () => {
        try{
          AsyncStorage.setItem("isLoggedIn", "true");
          AsyncStorage.setItem("jwt", token);
          setIsLoggedIn(true);
        }catch(e){
          console.log(e);
        }
      };
      
    /** logUserOut 함수 호출 : AsyncStorage에 로그인 여부 false 세팅, hook으로 로그인 여부 false 세팅 */
    const logUserOut = () => {
      try{
        AsyncStorage.setItem("isLoggedIn", "false");
        setIsLoggedIn(false);
      }catch(e){
        console.log(e);
      }
    };


      return (
            <AuthContext.Provider value={{isLoggedIn, logUserIn, logUserOut}} >
              {children}
            </AuthContext.Provider>
      );
};

export const useIsLoggedIn = () => {
  const {isLoggedIn} = useContext(AuthContext);
  console.log(isLoggedIn);
  return isLoggedIn;
};

export const useLogIn = () => {
  const {logUserIn} = useContext(AuthContext);
  return logUserIn;
};

export const useLogOut = () => {
  const {logUserOut} = useContext(AuthContext);
  return logUserOut;
};

 

 

댓글