본문 바로가기

웹 개발

웹 개발 공부 일기장 3 - 과제 (jwt 로그인 페이지)

2. jwt로 로그인 페이지 만들기

 

저번 jwt를 공부하면서 설명한 것처럼 직접 만들어 볼 수도 있겠지만, 어떤 방식으로 어떻게 구성되어있는지 알았기 때문에 제공하는 라이브러리를 사용하여 만들어보겠습니다.

 

일단 이 라이브러리를 사용하기 위해 다운로드 해야할 것이 있기때문에 아래 사이트에 들어가면 다운로드 하는 방법과 간단한 예제들을 볼 수 있습니다.

https://github.com/firebase/php-jwt

 

GitHub - firebase/php-jwt: PHP package for JWT

PHP package for JWT. Contribute to firebase/php-jwt development by creating an account on GitHub.

github.com

 

일단 먼저 아래와 같이 입력하여 php-jwt를 다운로드 받아줍니다.

composer require firebase/php-jwt

 

그리고 사용할 php 코드에 아래와 같이 입력해주면 준비는 끝!!!

use Firebase\JWT\JWT;
use Firebase\JWT\Key;
require_once('./vandor/autoload.php');

 

바로 제가만든 jwt 로그인 코드를 보겠습니다.

<?php
require_once('../data/database.php');
require_once('../views/includes/head.php');

use Firebase\JWT\JWT; // jwt라이브러리 사용
use Firebase\JWT\Key; // jwt 키 라이브러리 사용
require_once('../vendor/autoload.php');
$cookie = $_COOKIE;
// $cookie_jwt = $cookie['jwt'];
if ($cookie["jwt"]) {
  $jwt = $cookie["jwt"];
  $key = 'secret';
  $decoded = JWT::decode($jwt, new Key($key, 'HS256')); // jwt 확인
  $decoded_array = (array) $decoded;
  if ($decoded_array['userId']){
    echo 'hello '.$decoded_array['userId'];
    exit;
  }
} 
?>
</head>

<body>
  <form style="width: 50%; margin: 5rem auto;" method="post">
    <div class="form-floating mb-3">
      <input type="text" class="form-control" id="floatingInput" name="id" placeholder="Id">
      <label for="floatingInput">Id</label>
    </div>
    <div class="form-floating">
      <input type="password" class="form-control" id="floatingPassword" name="pw" placeholder="Password">
      <label for="floatingPassword">Password</label>
    </div>
    <input type="submit">
  </form>
  <?php
  // declare(strict_types=1);
  if ($_SERVER['REQUEST_METHOD'] == 'POST'){

  $enteredId = $_POST['id'];
  $enteredPw = $_POST['pw'];

  $query = "select * from users where id='$enteredId'";
  $users = mysqli_query($db_conn, $query);
  $user = mysqli_fetch_array($users);
  $userPw = $user['password'];
  $hashedPassword = hash('sha256', $enteredPw);
  mysqli_close($db_conn);
  if (!$user || $userPw != $hashedPassword) {
    echo '로그인 실패';
    exit;
  }; // 로그인 실패 시 jwt 생성 코드 실행하지않음


  $key = 'secret';
  $date = new DateTimeImmutable(); // 날짜와 시간을 표현하는 클래스
  $expire_at = $date->modify('+6 minutes')->getTimestamp(); // 토근 만료 시간을 6분으로 지정
  $domainName = "your.domain.name";
  $request_data = [
    'iat' => $date->getTimestamp(),
    // 이 데이터가 발행된 시간을 뜻합니다.
    'iss' => $domainName,
    // 이 데이터의 발행자를 뜻합니다.
    'nbf' => $date->getTimestamp(),
    // 이 데이터가 만료된 시간을 뜻합니다.
    'exp' => $expire_at,
    // 토큰이 처리되지 않아야 할 시점을 의미합니다. 이 시점이 지나기 전엔 토큰이 처리되지 않습니다.
    'userId' => $user['id'],
    // 다음 인증을 위한 데이터 입력
  ];

  $jwt = JWT::encode($request_data, $key, 'HS256'); // 데이터와 키를 사용하여 HS256 알고리즘을 통해 jwt 생성
  setcookie('jwt', $jwt); // 쿠키에 jwt 포함시킴 다음 요청 시 쿠키의 jwt로 요청 확인
	
  header('Location: /task3/login_jwt.php'); // 로그인 성공 후 다시 페이지 요청
  }
  ?>
</body>

</html>

 

JWT::encode(); 부분이 실제로 jwt토큰을 생성하는 부분이고,

JWT::decode(); 부분이 jwt의 내용을 보기위해 하는 부분입니다.

 

아!! 저는 실제로 작동하는 것을 보여드리기 위해 jwt를 쿠키에 넣어 실행했습니다. 쿠키에 넣어서 로그인을 구현해도 상관없다고 합니다.

 

간단히 설명하자면 처음에 쿠키에 jwt가 있는지 확인하고 있을 경우 decode를 통해 안에 저장되어있는 id를 가져와 로그인을 유지할 수 있습니다.

만약 쿠키에 jwt가 없다면 로그인 페이지를 보여주어 아이디와 비밀번호를 입력받아 로그인 성공 시 jwt를 생성하고 쿠키에 설정해줍니다.

 

실제 잘 작동하는지 확인해보고 이번주차 과제를 마치겠습니다.

로그인 실패 (아이디: admin, 비밀번호: guest)
로그인 성공 시 쿠키에 jwt 생성과 함께 hello [id] 출력