네이버 로그인 3

2024. 8. 13. 14:03Springboot-React

AuthContext.js

로그인한 멤버의 정보를 저장하는 context
새로고침을 하더라도 로그인한 정보가 풀리지 않음

import { createContext } from "react";

const AuthContext = createContext({
    loginMember : null, // 로그인한 멤버 정보를 저장할 변수
    setLoginMember : () => {} //로그인한 멤버 정보를 업데이트할 변수
    //setLoginMember -> loginMember로 전달
})
export default AuthContext;

 

AuthProvider.js

AuthContext에 저장된 값을 Provider가 감싸고 있는 모든 js에 저장된 값이 적용될 수 있도록 감싸는 js

import React from "react";
import AuthContext from "./AuthContext"; //provider가 감싸는 곳에 전파할 내용

const AuthProvider = () => {

    return(
        <>
            
        </>
    )
}
// export default가 필요 없음

 

 

App.js

import './App.css';
import NaverAPI from './component/NaverAPI';
import {BrowserRouter as Router, Route, Routes} from 'react-router-dom';
import NaverSignUp from './component/NaverSignUp';
import Header from './component/Layout/Header';
import { useEffect, useState } from 'react';
import AuthContext from './component/Layout/AuthContext';
import Login from './component/Login';

function App() {
  //로그인 정보를 받고 전달
  const [loginMember, setLoginMember] = useState(null);

  //로그인한 정보가 있다면 localStorage에 저장
  useEffect(() => {
    if(loginMember){
      localStorage.setItem("loginMember", JSON.stringify(loginMember));
    }
    //로그인한 멤버가 변경될 때마다 새로 저장
  }, [loginMember]);

  useEffect(() => {
    const savedMember =localStorage.getItem("loginMember");

    //만약 loginMember 변수에 저장된 회원 정보가 있다면 setLoginMember에 넣어주기
    if(savedMember){
      setLoginMember(JSON.parse(savedMember)); // 데이터 손실 방지를 위해 JSON 형식으로 변환
    }
  },[]);
  return (
    <AuthContext.Provider value={{loginMember, setLoginMember}}>
      <Router>
        <Header/>
          <Routes>
            <Route path='/login' element={<Login/>}/>
            <Route path='/api/naver' element={<NaverAPI/>}/>
            <Route path='/signup/naver' element= { <NaverSignUp/>}/>
          </Routes>
      </Router>
    </AuthContext.Provider>
  );
}

export default App;

 

이후 로그인을 진행할 Login.js

import { useState } from 'react';
import '../css/Login.css';
import axios from 'axios';

const Login = () => {
    const [id, setId] = useState('');
    const [password, setPassword] = useState('');
    const [message, setMessage] = useState('');
    
    //fetch
    const 로그인기능 = () => {
            fetch('http://localhost:9011/login', {
                method : 'POST',
                headers : {"Content-Type" : "application/json"},
                body : JSON.stringify({id, password})
            })
            .then(res => {
                if(res.ok){
                    return res.text();
                }  
            })
            .then(result => {
                setMessage(result); //자바에서 로그인 실패/성공 메시지 그대로 사용
            })
            .catch(err => {
                alert("에러 발생 : ", err);
            })
    }

	//axios
    const 로그인기능2 = () => {
        axios.post('http://localhost:9011/login', null, {
            params: {
                id: id,
                password: password
            }
        })
        .then(res => {
            if (res.status === 200) { // HTTP 상태 코드가 200일 경우
                setMessage("로그인 성공");
            }
        })
        .catch(err => {
            setMessage("로그인 중 문제가 발생");
            console.error("로그인 에러:", err);
        });
    }

    return (
        <div className='login-container'>
            <h3>로그인</h3>
            <div>
                <label> 아이디 :
                    <input placeholder="아이디" value={id} onChange={(e) => setId(e.target.value)}/>
                </label>
                <label> 비밀번호 :
                    <input type="password" placeholder="비밀번호" value={password} onChange={(e) => setPassword(e.target.value)}/>
                </label>
                <button onClick={로그인기능2}>로그인하기</button>
                {message && <p>{message}</p>}
                <div className='find-sign-buttons'>
                    <button>아이디찾기</button>
                    <button>비밀번호찾기</button>
                    <button>회원가입</button>
                </div>
            </div>
            <label>
                sns로 로그인하기 :
                <img src="/naver_image/btnG_iconRound.png" className='naver-logo-image'/>
            </label>
            {/*
            <button className='naver-login-button'>
                <img src="/naver_image/btnG_iconRound.png" />
                네이버로 회원가입
            </button>
            */}
        </div>
    )
}
export default Login;

 

그리고 java의 Controller에서 리액트에 맞춰줌

package com.kh.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.kh.dto.NaverUser;
import com.kh.service.LoginService;

@RestController
public class LoginController {

	@Autowired
	private LoginService service;
	/*
	parameters total 1 : 일치하는 컬럼이 1개 있음
	parameters total 0 : 일치하는 컬럼이 0개 있음
	*/
	@PostMapping("/login")
	//login @RequestBody Map<String, String>
	public ResponseEntity<String> Login(@RequestParam("id")String id, @RequestParam("password")String password) {
		NaverUser user = service.Login(id, password);
		System.out.println("아이디 : " + id + " 비밀번호 : " + password);
		if(user != null) {
			return ResponseEntity.ok("로그인 성공");
		}
		else {
			return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("로그인 실패");
		}
	}
}

 

** ResponseEntity.status(HttpStatus.UNAUTHORIZED)

ResponseEntity.status : DB나 어떤 값에 대한 결과 상태
HttpStatus : get, post 같은 메서드 기능이 동작했는지 확인
UNAUTHORIZED  : 인증 실패. 주로 로그인 실패

 

이제 DB에 있는 아이디와 비밀번호를 입력

 

서버측에서도 total : 1 이 뜬다. 로그인 성공

 

'Springboot-React' 카테고리의 다른 글

주소 api  (0) 2024.08.16
비밀번호 암호화  (0) 2024.08.14
프로필 사진 올리기 2  (1) 2024.08.09
프로필 사진 올리기 1  (0) 2024.08.09
이미지 여러개 올리기 2  (0) 2024.08.06