๋ชจ์ ํดํน ์คํฐ๋ - 3์ฃผ์ฐจ ๊ณผ์ (3-2) JWT ๊ตฌํ(๋ก๊ทธ์ธ ์ ์ง) ๋ฌธ์ ์ ๋ฐ๊ฒฌ
๊ธฐ์กด์ ๋ก๊ทธ์ธ ํ์ด์ง์ Develop ๊ณผ์
๋ชจ์ ํดํน ์คํฐ๋ - 3์ฃผ์ฐจ ๊ณผ์ (1) ๋ก๊ทธ์ธ ํ์ด์ง ๋ณด์
๋ชจ์ ํดํน ์คํฐ๋ - ๊ณผ์ 03์ฃผ์ฐจ(1) ๋ก๊ทธ์ธ ํ์ด์ง ๋ณด์
๋ชจ์ ํดํน ์คํฐ๋ - ๊ณผ์ 03์ฃผ์ฐจ(1) ๋ก๊ทธ์ธ ํ์ด์ง ๋ณด์ ๋ชจ์ ํดํน ์คํฐ๋ - 2์ฃผ์ฐจ ๊ณผ์ (๋ง์ดํ์ด์ง - ๋์ ์ ๋ณด) ๋ชจ์ ํดํน ์คํฐ๋ - ๊ณผ์ 02์ฃผ์ฐจ(3) (๋ง์ดํ์ด์ง - ๋์ ์ ๋ณด) ๋ชจ์ ํดํน ์คํฐ๋ - 2์ฃผ
codegear-archive.tistory.com
- ์์ ๊ณผ์ ๋ถํฐ JWT๋ฅผ ์ฌ์ฉ, ์ด์ ์๋ ์ธ์ (SESSION)์ ์ด์ฉ
- (๊ธฐ์กด์ ๊ณผ์ ์งํ์ ์์ด GET์ ์ด์ฉํ์ฌ ๋ค๋ฅธ ํ์ด์ง๋ก ์ ๋ณด๋ฅผ ๋ณด๋ด๋ ค ํ์)
- ๋ณด์์ ์ธ ๋ฌธ์ ๋ง ๋ฐ์ํ ๋ฟ, JWT๋ฅผ ์ด์ฉํ์ฌ ์ ๋ถ ๊ตฌํ ๊ฐ๋ฅ
์ฝ๋ ๋ชฉ๋ก ๋ฐ ๊ตฌ์ฑ
WebApp
โ
โ index.php
โ login.php
โ login_func.php
โ regist.php
โ regist.post.php
โ home.php
โ edit_pw.php
โ change.php
โ edit.php
โ update.php
โ withdraw.php
โ delete.php
โ
โโ inc
โ โโ db.php
โ โโ header.php
โ
โโ lib
โ โโ jwt.php
โ
โโ css
โโ style.css
JWT
lib/jwt.php
<?php
class JWT{
protected $alg;
protected $secret_key;
// ์์ฑ์
function __construct(){
// ์ฌ์ฉํ ์๊ณ ๋ฆฌ์ฆ
$this->alg = 'sha256';
// ๋น๋ฐ ํค
$this->secret_key = "your secret key";
}
// JWT ๋ฐ๊ธ(hash) - Header . PayLoad . Signature
function hashing(array $data): string{
// Header(ํค๋) - alg (์ฌ์ฉํ ์๊ณ ๋ฆฌ์ฆ), typ (ํ์
) ๋ช
์
$header = json_encode(array(
'alg' => $this->alg,
'typ' => 'JWT'
));
// PayLoad(ํ์ด๋ก๋) - ์ ๋ฌํ ๋ฐ์ดํฐ
$payload = json_encode($data);
// Signature(์๋ช
)
$signature = hash($this->alg, $header . $payload . $this->secret_key);
// JSON ํํ์ ๊ฐ์ฒด๋ฅผ base64๋ก ์ธ์ฝ๋ฉ
return base64_encode($header . '.' . $payload . '.' . $signature);
}
// JWT ํด์(dehash) - ์ฌ์ฉ์ ๊ฒ์ฆ
function dehashing($token){
// ํ ํฐ(base64 ๋์ฝ๋ฉ) ๋ถํ (๊ตฌ๋ถ์ . ๊ธฐ์ค) - ๋ฐฐ์ด๋ก ์ ์ฅ
$parted = explode('.', base64_decode($token));
$signature = $parted[2];
// ํ ํฐ ๋ฐ๊ธ์์ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก Signature ์์ฑ ํ ๋น๊ต
if(hash($this->alg, $parted[0] . $parted[1] . $this->secret_key) != $signature){
return "Signature Error";
}
// ๋ง๋ฃ ๊ฒ์ฌ - payload ์ exp
$payload = json_decode($parted[1], true);
// 'ํ ํฐ ๋ง๋ฃ ์๊ฐ'์ด 'ํ์ฌ ์๊ฐ'๋ณด๋ค ์ ์ด๋ฉด
if($payload['exp'] < time()) {
return 'Expired';
}
/*
* ๊ธฐํ ํ ํฐ ํ์ธ ์์
*/
return json_decode($parted[1], true);
}
}
$jwt = new JWT();
?>
![]() |
![]() |
![]() |
![]() |
![]() |
- ์์ ํ์์ ๋ณด๋ฉด, ์ฟ ํค๋ฅผ ์ด์ด๋ณด์์ ๋, ๋ก๊ทธ์ธ ์ ์๋ PHPSESSID๋ง ์กด์ฌํ๊ณ , ๋ก๊ทธ์ธ ํ์๋ token์ด ์๊ธด ๊ฒ์ ํ์ธํ ์ ์์
- ํ ํฐ ๋ฐ๊ธ ์ด์ ์๋ ํค๋๊ฐ '๋ก๊ทธ์ธ/ํ์๊ฐ์ ' ์ด์ง๋ง, ํ ํฐ์ด ๋ฐ์๋ ํ์๋ inc/header.php ์์ ํ ํฐ ์กด์ฌ๋ฅผ ํ์ธํ๊ณ '๋ก๊ทธ์์' ์ผ๋ก ๋ฐ๋ ๊ฒ์ ํ์ธํ ์ ์์
- __construct() : ์์ฑ์
- ์ฌ์ฉํ ์๊ณ ๋ฆฌ์ฆ์ ๊ฒฐ์ : alg = 'sha256'
- ์ฌ์ฉํ ๋น๋ฐ ํค๋ฅผ ์ง์ : secret_key = "your secret key"
- JWT ๋ฐ๊ธ
- hashing(array $data): string ํจ์๋ฅผ ์ด์ฉ
- (hash) Header . PayLoad . Signature
- Header(ํค๋) - alg (์ฌ์ฉํ ์๊ณ ๋ฆฌ์ฆ), typ (ํ์
) ๋ช
์
- alg ๋ ์์ฑ์์์ ๋ฐ์์ด
- typ์ JWT
- PayLoad(ํ์ด๋ก๋) - ์ ๋ฌํ ๋ฐ์ดํฐ
- $payload = json_encode($data);
- $data๋ hashing ์ฌ์ฉ ์์ ๋ฃ์ด์ค
- (data๋ฅผ json ์ธ์ฝ๋ฉ)
- Signature(์๋ช
)
- $signature = hash($this->alg, $header . $payload . $this->secret_key);
- ์๋ช ์ ํค๋, ํ์ด๋ก๋๋ฅผ ํฉ์น๊ณ , ์ฌ์ฉ ์๊ณ ๋ฆฌ์ฆ์ ๊ธฐ๋ฐ์ผ๋ก ๋น๋ฐํค์ ํจ๊ป ํด์ ๋ณํ
- JSON ํํ์ ๊ฐ์ฒด๋ฅผ base64๋ก ์ธ์ฝ๋ฉ
- base64_encode($header . '.' . $payload . '.' . $signature);
- hashing(array $data): string ํจ์๋ฅผ ์ด์ฉ
- JWT ํด์
- dehashing($token) ํจ์๋ฅผ ์ด์ฉ
- (dehash) - ์ฌ์ฉ์ ๊ฒ์ฆ
- ๋ฐ์์จ ํ ํฐ(base64 ๋์ฝ๋ฉ)์ ๋ถํ ํ์ฌ (๊ตฌ๋ถ์ . ๊ธฐ์ค) ๋ฐฐ์ด๋ก ์ ์ฅ
- $parted = explode('.', base64_decode($token));
- $parted[0] ๋ Header
- $parted[1] ๋ Payload
- $parted[2] ๋ Signatue
- ํ ํฐ ๋ฐ๊ธ์์ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก Signature ์์ฑ ํ ๋น๊ต
- if(hash($this->alg, $parted[0] . $parted[1] . $this->secret_key) != $signature)
- ํ์ด๋ก๋์ ๋ง๋ฃ ๊ฒ์ฌ
- $payload = json_decode($parted[1], true);
- 'ํ ํฐ ๋ง๋ฃ ์๊ฐ'์ด 'ํ์ฌ ์๊ฐ'๋ณด๋ค ์ ์ด๋ฉด ํ๊ธฐ
- if($payload['exp'] < time()) :
- ๊ธฐํ ํ ํฐ์ ๋ด์ฉ์ ๋ํ ํ์ธ์ด ๊ฐ๋ฅํ์ง๋ง, ์ด๋ฒ ๊ตฌํ์๋ ํ์ธํ์ง ์์
- json ๋์ฝ๋ฉ์ ํตํด $data๊ฐ์ ๋ฐํ
- json_decode($parted[1], true);
- JWT ์ฌ์ฉ ์ ์ธ
- $jwt = new JWT();
- ์ฌ๊ธฐ์ ์ ์ธํด ์ค์ผ ์ฌ์ฉ์ ๋ฌธ์ ๊ฐ ์์์
- dehashing($token) ํจ์๋ฅผ ์ด์ฉ
JWT ์ ์ฉ
- login_func.php ์์ ๋ก๊ทธ์ธ ์กฐ๊ฑด์ ๋ถํฉํ๋ฉด, ๋ก๊ทธ์ธ๋๋ ์ ์ ์ ์ ๋ณด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก JWT(JSON Web Token)์ ๋ฐํ
ํ ํฐ ๋ฐ๊ธ(๋ก๊ทธ์ธ)
login_func.php
<?php
require_once("inc/db.php");
require_once("lib/jwt.php");
$userID = isset($_POST['userID']) ? $_POST['userID'] : null;
$pass = isset($_POST['pass']) ? $_POST['pass'] : null;
// ํ๋ผ๋ฏธํฐ ์ฒดํฌ
if($userID == null || $pass == null){
header("Location: /login.php");
exit();
}
// ํ์ ๋ฐ์ดํฐ ์กฐํ
$db_conn = db_connect();
$sql = "SELECT * FROM userTbl WHERE userID= '$userID'";
$ret = mysqli_query($db_conn, $sql);
// ํ์ ๋ฐ์ดํฐ๊ฐ ์๋ค๋ฉด
$row = mysqli_fetch_array($ret);
$cnt = mysqli_num_rows($ret);
if($row['userID'] == null || $cnt == 0){
echo '<script>alert("๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ์ฐพ์ ์ ์๊ฑฐ๋ ์๋ชป ์
๋ ฅ"); history.back(-1)</script>';
exit();
}
// ๋น๋ฐ๋ฒํธ ์ผ์น ์ฌ๋ถ ํ์ธ
$is_pw = password_verify($pass, $row['pass']);
if($is_pw === false){
echo '<script>alert("๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ์ฐพ์ ์ ์๊ฑฐ๋ ์๋ชป ์
๋ ฅ"); history.back(-1)</script>';
exit();
}
// ๋ก๊ทธ์ธ ์กฐ๊ฑด ๋ฌ์ฑ(jwt์ ๋ค์ด๊ฐ ์ ๋ณด)
$id = $row['userID'];
$name = $row['name'];
// $email = $row['email'];
// // e-mail ์ ๊ฒฝ์ฐ . ์ด ๋ค์ด๊ฐ๊ธฐ ๋๋ฌธ์, (.)์ด ๋ค์ด๊ฐ๋ JWT๊ฐ ๋ถ๋ฆฌ๋์ง ์๊ธฐ ์ํ base64 ์ธ์ฝ๋ฉ
// $email = base64_encode($email);
// ์ ์ ์ ๋ณด๋ฅผ ๊ฐ์ง jwt ๋ง๋ค๊ธฐ
$token = $jwt->hashing(array(
'exp' => time() + (3600), // ๋ง๋ฃ ์๊ฐ
'iat' => time(), // ๋ฐ๊ธ ์๊ฐ
// ์ ์ ์ ๋ณด (pass ์ ์ธ)
'id' => $id,
'name' => $name,
// 'email' => $email,
));
// ๋ง๋ฃ ์๊ฐ์ด token๊ณผ ๋์ผํ ์ฟ ํค์ token์ ๋ฃ์ด์ค(๊ตฌ์ง ๊ฐ์ ์ด์ X)
setcookie("login_token", $token, time() + (3600));
mysqli_close($db_conn);
header("Location: /home.php");
?>
- JWT๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด incluing
- require_once("lib/jwt.php");
- ๋ก๊ทธ์ธ ๊ณผ์ ์์ฒด๋ ๊ธฐ์กด๊ณผ ๋์ผ (์๋ณ/์ธ์ฆ ๋ถ๋ฆฌ with hash)
- ๋ก๊ทธ์ธ ์กฐ๊ฑด์ ๋ถํฉํ๋ ๊ฒฝ์ฐ
- jwt์ ๋ฃ์ ์ฌ์ฉ์ ์ธ์ฆ์ ์ํด ํ์ํ ์ ๋ณด
- userID, userName : ์๋ณ์ ์ํจ
- pass์ ๊ฒฝ์ฐ ๋ฏผ๊ฐ์ ๋ณด์ด๊ธฐ ๋๋ฌธ์ ๋ฃ์ง ์์
- ๋ง์ฝ email๊ณผ ๊ฐ์ด ์ (.)์ด ๋ฐ์ดํฐ ์์ฒด์ ๋ค์ด๊ฐ๋ ๊ฒฝ์ฐ
- ์ (.)์ ์ํด [ํค๋] . [ํ์ด๋ก๋] . [์๋ช ] ์ด์ธ์ ๋ถ๋ฆฌ๋์ง ์๋๋ก ํด์ผํจ
- base64 ์ธ์ฝ๋ฉ์ ์ด์ฉ ์ (.)์ ์์ ์ค
- ์์ ๋ ๊ณผ์ ์์ ๋ฑํธ(=) ๊ฐ ์๊ธฐ๋ ๊ฒฝ์ฐ, (=)๋ ์ญ์ ํด์ค๋ ๋ฌด๋ฐฉ
- jwt ๋ฐ๊ธ
- ๋ง๋ฃ์๊ฐ(exp) : time() or now() + (์ ์งํ ์๊ฐ)
- ๋ฐ๊ธ์๊ฐ(exp) : time() or now()
- ์ฟ ํค(Cookie) ์์ฑ
- ๋ฐ๊ธ๋ JWT๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์ฟ ํค์ ๋ฃ์ด ์ค
ํ ํฐ ํด์(์ฌ์ฉ์ ์ธ์ฆ)
home.php
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8">
<title>Home</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class ="container">
<h1 class="spacing grad">Home</h1>
<?php require_once("inc/header.php"); ?>
<?php
require_once("lib/jwt.php");
// Cookie ์์ jwt ๊ฐ์ ธ์ค๊ธฐ
$token = $_COOKIE['login_token'];
// jwt์์ ์ ์ ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ
$data = $jwt->dehashing($token);
echo "์๋
ํ์ธ์, " . $data['name'] . " ๋";
echo "<br><br>";
echo "์ฌ๊ธฐ๋ ํ ํ์ด์ง ์
๋๋ค.<br><br>";
?>
<p style='text-align:left'>
<a href='/mypage.php'>๋ง์ดํ์ด์ง</a>
<a href='/edit_pw.php'>๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ</a>
<a href='/withdraw.php'>ํ์ ํํด</a>
</p>
</div>
</body>
</html>
- JWT๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด including
- require_once("lib/jwt.php");
- Cookie ์์ jwt ๊ฐ์ ธ์ค๊ธฐ
![]() |
![]() |
- ๋ก๊ทธ์ธ์ด ๋๊ณ ๋๋ฉด ์์๊ฐ์ด login_token์ด ์ฟ ํค์ ๋ค์ด์๋ ๊ฒ์ ํ์ธํ ์ ์์
- $token = $_COOKIE['login_token']; ์ ์ด์ฉํ์ฌ ์ฟ ํค์์ ํด๋น ํ ํฐ์ ๊ฐ์ ธ์ด
- jwt์์ ์ ์ ์ ๋ณด ์ถ์ถ
- $data = $jwt->dehashing($token);
- dehash ๋ ํ ํฐ์ ๊ธฐ์กด์ ์ฝ์ ํ ๋ฐ์ดํฐ์ ๋ฐฐ์ด
- ํ์ํ ๋ฐ์ดํฐ๋ฅผ $data['name'] ํ์์ผ๋ก ๋ถ๋ฌ์ฌ ์ ์์
ํ ํฐ ํ๊ธฐ(๋ก๊ทธ์์)
index.php
<?php
setcookie("login_token", $token, time()-(360*30));
?>
<!DOCTYPE html>
<html>
<head>
<title>Index Page</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<h1 class="spacing grad">Index ํ์ด์ง</h1>
<?php require_once("inc/header.php"); ?>
<h2>๋ก๊ทธ์ธํด์ฃผ์ธ์.</h2>
<p>์์ด๋๊ฐ ์๋ค๋ฉด ํ์๊ฐ์
.</p>
</div>
</body>
</html>
- ๋ก๊ทธ์์ ์์ index ์ฐฝ์ผ๋ก ๋ฆฌ๋๋ ์
๋๊ณ , ์ฟ ํค์ ์๊ฐ์ 0์ดํ๋ก ๋ง๋ค์ด์ค์ผ๋ก์จ ์์ ๋ค์ด์๋ ํ ํฐ์ ์ญ์
- setcookie("login_token", $token, time()-(360*30));
- ๋ฌธ์ ์
- ํด๋น ํ์ด์ง๋ก ๋ฆฌ๋๋ ์ ๋ ๋ ์ฟ ํค๋ฅผ ์ญ์ ํ์ฌ ํ ํฐ์ ์ง์ฐ๋ค ๋ณด๋
- inc/header.php ์์ ์ธ์ํ๊ฒ ํ๊ธฐ ์ํด ํ๋ฒ ์๋ก๊ณ ์นจํด์ค์ผ '๋ก๊ทธ์์' -> '๋ก๊ทธ์ธ/ํ์๊ฐ์ ' ์ผ๋ก ๋ฐ๋
- ํ์ด์ง๋ฅผ ์๋ก ๊ณ ์น๋ ํ์๋ ๊ผผ์์ ์๋จ (ํ์ด์ง๋ฅผ ํ๋ฒ ๋ ๋ก๋ํด์ผํ๋ ๊ฒ...)
- ์๋ก๊ณ ์นจ์ ๊ฒฝ์ฐ
- echo("<meta http-equiv='refresh' content='0'>"); ํ์์ผ๋ก ๊ฐ๋ฅํ์ง๋ง
- ํ๋ฒ๋ง ์๋ก๊ณ ์ณ์ผํ๋๋ฐ, ์ ๋๋ก ๊ตฌํํ์ง ๋ชปํจ
์์ง ๋ฏธ๊ตฌํ์ธ ๋ถ๋ถ
๋ก๊ทธ์ธ ์ ์ง
- refresh_token : ๋ก๊ทธ์ธ ์ ์ง๋ฅผ ์ํ Access Token ์ฐ์ฅ์ฉ Token
- ์ฒดํฌ๋ฐ์ค ์ ๋ ฅ์ ํตํด ๋ก๊ทธ์ธ ์ ์ง๋ฅผ ์ฒดํฌํ๊ฑฐ๋
- ํ ํฐ์ ์๊ฐ์ ๋๋ ค์ค์ผํ๋ ๊ฒฝ์ฐ
- jwt ์ญ์ ( ์ฟ ํค๋ฅผ ๋ง๋ฃ์์ผ ๊ตฌํ์ ์์ผฐ์ง๋ง, ์๋ฒฝํ๊ฒ ๋์ํ์ง ์๋ ์ํ )
ํ๊ธฐ
- index.php๋ก ๋ฆฌ๋๋ ์ ๋ ๋๊ฐ ์๋, ๋ก๊ทธ์์์ ๋๋ ์ ๋ ์ฟ ํค๋ฅผ ๋ฐ๋ก ์ญ์ ํ๊ณ ๋์ด๊ฐ์ผํ ๊ฒ ๊ฐ์ง๋ง.
- ์์ง ๋ฒํผ ๊ตฌํ ๋ฐ ์ฌ์ฉ์ ๋ํ์ฌ ์ต์ํ์ง ์์ ์ฐ์ ์ ์ผ๋ก ๋์์ด ๋๋ ๊ฒ๋ง์ ํ์ธ
- jwt ๋ฐ๊ธ/ ํด์ ์ ๊ทธ๋๋ ์ด๋์ ๋ ์ดํด๊ฐ ๊ฐ๊ณ ์งํ์ด ๋์์ผ๋ ์ ์ง ๊ด๋ฆฌ์ ๋ฌธ์ ๋ ๋ ๋ค๋ฅธ๊ฒ์์ ๊นจ๋ฌ์
- ํ์ง๋ง ์ด๋ป๊ฒ ๋ณด๋ฉด ์ ์ง ๊ด๋ฆฌ๊ฐ ๋ณด์ ์ธก๋ฉด์์๋ ๋ ์ค์ํ๊ฒ ์๋๊น?
์ง๋ฌธ ํ์, ์์ ๋ฐ ๋ณด์์ ๋ํ ์ง์ ํ์