React 에서 RSA 암호화를 하여 패스워드를 Back-End(PHP)로 전송하고, PHP에서 복호화 처리를 해봤다.
npm install jsencrypt@3.2.1
로 모듈을 추가하고 아래와 같이 코드를 전송하면 된다.
jsencrypt 버전은 3.2.1 에서 정상동작함을 확인했다.
import {useState} from "react";
import {Link, useNavigate} from "react-router-dom";
import axios from "axios";
import { JSEncrypt } from "jsencrypt"; // npm install jsencrypt
const Login = () => {
// PHP 를 이용하여 Web에서 생성한 공개키 : 실제 길이는 훨씬 더 길다.
const publicKey = `MIGfMA0GCSqGSIb3DQEBED/dKAJT7vdgzXooBzzTyUHwVJGyA1mKYDCIyU5/IQIDAQAB`;
const encrypt = new JSEncrypt(); // Start our encryptor.
encrypt.setPublicKey(publicKey); // Assign our encryptor to utilize the public key.
const navigate = useNavigate();
const initData = {
userID: '',
password: ''
}
const [formData, setFormData] = useState(initData);
const [users, setUsers] = useState([]);
// 첫번째 원소 : 현재 상태, 두번재 원소 : 상태를 바꾸어 주는 함수
const [error, setError] = useState(null);
const onChangeInput = (e) => {
setFormData({
...formData,
[e.target.name]: e.target.value
});
// e.target.name 은 해당 input의 name을 가리킨다.
//console.log(formData);
}
const submitForm = (e) => {
e.preventDefault();
const params = {
userID: formData.userID,
password: encrypt.encrypt(formData.password)
}
console.log(params);
axios.post('/reactSample/loginChk.php', params)
.then((res) => {
console.log(res);
if (res.status === 200 && res.data.status === 'success') {
setUsers(res.data.userinfo);
navigate('/');
} else {
console.log(res.data.message);
setError(true);
}
})
.catch(error => {
console.log(error.response)
});
}
return (
<div className="container h-100 mt-5">
<div className="row d-flex justify-content-center align-items-center h-100">
<div className="col-12 col-md-9 col-lg-7 col-xl-6">
<div className="card">
<div className="card-body p-5">
<h2 className="text-uppercase text-center mb-5">Sign In</h2>
<form onSubmit={submitForm}>
<div className="form-outline mb-4">
<label className="form-label" htmlFor="userID">userID</label>
<input type="text" name="userID" onChange={onChangeInput} id="userID"
className="form-control form-control-lg" value={formData.userID}
required/>
</div>
<div className="form-outline mb-4">
<label className="form-label" htmlFor="password">Password</label>
<input type="password" name="password" onChange={onChangeInput} id="password"
className="form-control form-control-lg" value={formData.password}
required/>
</div>
{ error &&
<div className="alert alert-danger" role="alert">
로그인 정보를 확인하세요!
</div>
}
<div className="d-flex justify-content-center">
<button type="submit"
className="btn btn-primary btn-block btn-lg gradient-custom-3 text-body">로그인
</button>
</div>
<p className="text-center text-muted mt-5 mb-0">
<Link to="/register" className="fw-bold text-body"><u>회원가입</u></Link>
</p>
</form>
</div>
</div>
</div>
</div>
</div>
)
}
export default Login;
|
cs |
PHP 에서 RSA 공개키 얻는 방법
<?php
header("Cache-Control: no-cache, must-revalidate");
header("Content-type: application/json; charset=UTF-8");
$pubkey = get_publickey();
echo $pubkey;
function get_publickey() {
// 경로 : 절대경로로 설정 필요
$rsakeyfile = '/home/rsa/key/rsa_pub.pem';
$fp = fopen($rsakeyfile,"r");
$key = "";
while(!feof($fp)) {
$key .= fgets($fp,4096);
}
fclose($fp);
$key = preg_replace('/\r\n|\r|\n/','',$key);
$key = str_replace('-----BEGIN PUBLIC KEY-----','',$key);
$key = str_replace('-----END PUBLIC KEY-----','',$key);
return $key;
}
/*
CentOS 리눅스 에서 RSA 공개키, 개인키 생성 방법
mkdir -p /home/rsa/key/
cd /home/rsa/key/
# Private Key 생성
openssl genrsa -out rsa_pri.pem 1024
# Public Key 생성
openssl rsa -pubout -in rsa_pri.pem -out rsa_pub.pem
*/
?>
|
PHP loginChk.php
- RSA 복호화 처리 함수는 LoginClass.php 파일에 포함되어 있다.
<?php
// 파일을 직접 실행하는 비정상적 동작을 방지 하기 위한 목적
if(isset($_POST) && $_SERVER['REQUEST_METHOD'] == "POST"){
$_POST = json_decode(file_get_contents("php://input"),true);
@extract($_POST); // $_POST['loginID'] 라고 쓰지 않고, $loginID 라고 써도 인식되게 함
if(isset($userID) && !empty($userID) && isset($password) && !empty($password)) {
require_once 'phpclass/config.php';
require_once 'phpclass/dbconnect.php';
require_once 'phpclass/loginClass.php';
$c = new LoginClass();
header("Cache-Control: no-cache, must-revalidate");
header("Content-type: application/json; charset=UTF-8");
$password = $c->rsa_decrypt($password);
$user = $c->getUser($userID, $password);
if($user['idx'] == 1){ // 로그인 정보가 일치하면
$_SESSION['userID'] = $user['userID'];
$_SESSION['userNM'] = $user['userNM'];
$_SESSION['admin'] = $user['admin'];
$row = array("userNM"=>$user['userNM'],"mobileNO"=>$user['mobileNO'],"profileImg"=>$user['idx']);
$status = "success";
$message = "";
$userinfo = $row;
} else {
$status = "로그인 에러";
$message = "다시 한번 시도하시기 바랍니다.";
$userinfo = null;
}
$result = array(
'status' => $status,
'message' => $message,
'userinfo' => $userinfo
);
echo json_encode($result);
}
} else { // 비정상적인 접속인 경우
echo 0; // loginChk.php 파일을 직접 실행할 경우에는 화면에 0을 찍어준다.
exit;
}
?>
|
'React > React-PHP' 카테고리의 다른 글
React + PHP Login 처리 (0) | 2022.08.27 |
---|---|
React useEffect example (php REST API) (0) | 2022.08.22 |
React - PHP 간 연동 입문기 (0) | 2022.08.20 |