[실습] 도커 실습 8 - Redis을 활용한 마이크로 서비스의 세션 공유
필기자
2024-11-05 08:34
312
0
본문
목차
마이크로 서비스 세션 공유
시나리오
user DB 테이블 생성 및 데이터 삽입
redis 세션 연동 설정
로그인 처리 및 redis 세션 생성 파일 생성
tasks-list.php 세션 공유 내용 추가
app.js 세션 공유 내용 추가
로그아웃 기능
- 마이크로 서비스 세션 공유
마이크로 서비스 세션 공유
시나리오
- 로그인 화면 생성
- user DB 테이블 생성 및 데이터 삽입
- 로그인 처리 및 redis 세션 생성 파일 생성
- tasks-list.php 세션 공유 내용 추가
- app.js 세션 공유 내용 추가
- 로그아웃 기능
- /home/kky/html/login.html
<!doctype html>
<html>
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<title>로그인 페이지</title>
<link
href='https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css'
rel='stylesheet'>
<link href='#' rel='stylesheet'>
<script type='text/javascript'
src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>
<style>
::-webkit-scrollbar {
width: 8px;
}
/* Track */
::-webkit-scrollbar-track {
background: #f1f1f1;
}
/* Handle */
::-webkit-scrollbar-thumb {
background: #888;
}
/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
background: #555;
}
body {
background-color: #f9f9fa;
}
.flex {
-webkit-box-flex: 1;
-ms-flex: 1 1 auto;
flex: 1 1 auto
}
@media ( max-width :991.98px) {
.padding {
padding: 1.5rem
}
}
@media ( max-width :767.98px) {
.padding {
padding: 1rem
}
}
.padding {
padding: 5rem
}
.card {
background: #fff;
border-width: 0;
border-radius: .25rem;
box-shadow: 0 1px 3px rgba(0, 0, 0, .05);
margin-bottom: 1.5rem
}
.card-header {
background-color: transparent;
border-color: rgba(160, 175, 185, .15);
background-clip: padding-box
}
.card-body p:last-child {
margin-bottom: 0
}
.card-hide-body .card-body {
display: none
}
.form-check-input.is-invalid ~.form-check-label, .was-validated .form-check-input:invalid
~.form-check-label {
color: #f54394
}
</style>
</head>
<body className='snippet-body'>
<div id="content" class="flex">
<div class="">
<div class="page-content page-container" id="page-content">
<div class="padding">
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<strong>Login to your account</strong>
</div>
<div class="card-body">
<form>
<div class="form-group">
<label class="text-muted" for="myEmail">Email
address</label><input type="email" class="form-control"
id="myEmail" aria-describedby="emailHelp"
placeholder="Enter email"> <small id="emailHelp"
class="form-text text-muted">We don't share email
with anyone</small>
</div>
<div class="form-group">
<label class="text-muted" for="myPassword">Password</label><input
type="password" class="form-control"
id="myPassword" placeholder="Password"> <small
id="passwordHelp" class="form-text text-muted">your
password is saved in encrypted form</small>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script type='text/javascript'
src='https://stackpath.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.bundle.min.js'></script>
<script>
$(function(){
$("form").on("submit", function(event) {
event.preventDefault(); // 기본 동작 중단
// 입력 값을 가져옴
var email = $("#myEmail").val();
var password = $("#myPassword").val();
// AJAX로 POST 요청을 보냄
$.ajax({
url: "/user/login.php", // 로그인 처리를 하는 서버의 URL
type: "POST",
dataType: "json", // 서버에서 받는 데이터 타입
data: {
email: email,
password: password
},
success: function(data) {
// 로그인 성공 시 처리
alert(data.msg);
if(data.result == "ok"){
window.location.href = "/";
}
console.log("Login successful:", data);
},
error: function(xhr, status, error) {
// 로그인 실패 시 처리
console.log("Login failed:", error);
}
});
});
});
</script>
</body>
</html>
user DB 테이블 생성 및 데이터 삽입
redis 세션 연동 설정
- /home/kky/php/user/database.php 수정
- /home/kky/php/task/database.php 수정
//header("Access-Control-Allow-Origin: *"); // Cross origin
$mysql_host = "mysql"; // 172.26.0.2
$mysql_user = "php-mysql";
$mysql_password = "123456";
$mysql_db = "php-mysql";
$connection = mysqli_connect(
$mysql_host, $mysql_user, $mysql_password, $mysql_db
);
include_once("./redis_session.php");
로그인 처리 및 redis 세션 생성 파일 생성
- /home/kky/php/user/login.php
include_once("./database.php");
$ret = array();
// 세션 시작
session_start();
if(!isset($_POST['email']) || $_POST['email'] == ""){
$ret['result'] = "no";
$ret['msg'] = "이메일 정보가 없습니다.";
$jsonstring = json_encode($ret, JSON_UNESCAPED_UNICODE);
echo $jsonstring;
exit;
}
if(!isset($_POST['password']) || $_POST['password'] == ""){
$ret['result'] = "no";
$ret['msg'] = "패스워드 정보가 없습니다.";
$jsonstring = json_encode($ret, JSON_UNESCAPED_UNICODE);
echo $jsonstring;
exit;
}
$query = "SELECT * from user where email='{$_POST['email']}' and pass='{$_POST['password']}'";
$result = mysqli_query($connection, $query);
if (!$result) {
$ret['result'] = "no";
$ret['msg'] = "데이터베이스 연결 오류";
$jsonstring = json_encode($ret, JSON_UNESCAPED_UNICODE);
echo $jsonstring;
exit;
}
$row = mysqli_fetch_array($result);
if(!isset($row['email'])){
$ret['result'] = "no";
$ret['msg'] = "로그인 정보가 틀립니다.";
$jsonstring = json_encode($ret, JSON_UNESCAPED_UNICODE);
echo $jsonstring;
exit;
}else{
$_SESSION['username'] = $row['name'];
$_SESSION['useremail'] = $row['email'];
$ret['result'] = "ok";
$ret['msg'] = "정상 로그인이 되었습니다.";
$jsonstring = json_encode($ret, JSON_UNESCAPED_UNICODE);
echo $jsonstring;
exit;
}
- 로그인 테스트 http://gctask.com/login.html
tasks-list.php 세션 공유 내용 추가
- /home/kky/php/task/tasks-list.php
include_once("./database.php");
$ret = array();
// 세션 시작
session_start();
if (!isset($_SESSION['username']) || $_SESSION['username'] == "") {
$ret['result'] = "no";
$ret['msg'] = "로그인을 해주십시오.";
$jsonstring = json_encode($ret, JSON_UNESCAPED_UNICODE);
echo $jsonstring;
exit;
}
$query = "SELECT * from task";
$result = mysqli_query($connection, $query);
if (!$result) {
die('Query Failed' . mysqli_error($connection));
}
$json = array();
while ($row = mysqli_fetch_array($result)) {
$json[] = array(
'name' => $row['name'],
'description' => $row['description'],
'id' => $row['id']
);
}
$ret['result'] = "ok";
$ret['msg'] = "정상적으로 데이터를 가져왔습니다.";
$ret['tasks'] = $json;
$ret['username'] = $_SESSION['username'];
$jsonstring = json_encode($ret, JSON_UNESCAPED_UNICODE);
echo $jsonstring;
app.js 세션 공유 내용 추가
- /home/kky/html/app.js 에서 fetchTasks() 함수 수정
// Fetching Tasks
function fetchTasks() {
$.ajax({
url: hostNameServerUrl+'tasks-list.php',
type: 'GET',
dataType: "json", // 서버에서 받는 데이터 타입
success: function(tasks) {
//const tasks = JSON.parse(response);
if(tasks.result == "ok"){
const list = tasks.tasks;
let template = '';
list.forEach(task => {
template += `
<tr taskId="${task.id}">
<td>${task.id}</td>
<td><a href="#" class="task-item"> ${task.name} </a></td>
<td>${task.description}</td>
<td>
<button class="task-delete btn btn-danger" data-taskId="${task.id}" >Delete</button>
</td>
</tr>
`
});
$('#tasks').html(template);
$('.user-name').remove();
$(".table-bordered").before("<p class='user-name'>"+tasks.username+"님의 할일</p>");
}else{
alert(tasks.msg);
window.location.href = "/login.html";
}
}
});
}
- 최종 로그인 테스트 및 세션 공유 확인
- http://gctask.com/login.html
로그아웃 기능
- 메인에서 로그아웃 버튼 추가
- /home/kky/html/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Todo App</title>
<!-- BOOTSTRAP 4 -->
<link rel="stylesheet" href="https://bootswatch.com/4/lux/bootstrap.min.css">
</head>
<body>
<!-- NAVIGATION -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="#">Tasks App</a>
<button class="navbar-toggler" type="button" data-toggle="collapse"
data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ml-auto">
<form class="form-inline my-2 my-lg-0">
<input name="search" id="search" class="form-control mr-sm-2"
type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
<div class="container">
<div class="row p-4">
<div class="col-md-5">
<div class="card">
<div class="card-body">
<!-- FORM TO ADD TASKS -->
<form id="task-form">
<div class="form-group">
<input type="text" id="name" placeholder="Task Name"
class="form-control">
</div>
<div class="form-group">
<textarea id="description" cols="30" rows="10"
class="form-control" placeholder="Task Description"></textarea>
</div>
<input type="hidden" id="taskId">
<button type="submit"
class="btn btn-primary btn-block text-center">Save Task
</button>
</form>
</div>
</div>
</div>
<!-- TABLE -->
<div class="col-md-7">
<div class="card my-4" id="task-result">
<div class="card-body">
<!-- SEARCH -->
<ul id="container"></ul>
</div>
</div>
<table class="table table-bordered table-sm">
<thead>
<tr>
<td>Id</td>
<td>Name</td>
<td>Description</td>
</tr>
</thead>
<tbody id="tasks"></tbody>
</table>
<div><button id="logout" class="btn btn-warning">로그아웃</button></div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script>
$(function(){
$("#logout").click(function(){
$.ajax({
url: '/user/logout.php',
type: 'POST',
dataType: "json", // 서버에서 받는 데이터 타입
success: function(data) {
//const tasks = JSON.parse(response);
if(data.result == "ok"){
alert(data.msg)
window.location.href = "/login.html";
}else{
alert(data.msg);
}
}
});
});
});
</script>
<!-- Frontend Logic -->
<script src="app.js"></script>
</body>
</html>
- 로그아웃 기능 추가
- /home/kky/user/logout.php
include_once('redis_session.php');
$ret = array();
// 세션 시작
session_start();
$_SESSION['username'] = "";
$_SESSION['useremail'] = "";
unset($_SESSION['username']);
unset($_SESSION['useremail']);
$ret['result'] = "ok";
$ret['msg'] = "로그아웃 되었습니다.";
//$ret['useremail'] = $_SESSION['useremail'];
echo json_encode($ret, JSON_UNESCAPED_UNICODE);
댓글목록0