初めに
今回は、前回のログインサーバーを改造します(?)
前回とちがうところ
前回は一つのユーザーまでしか認証ができませんでしたが、今回はユーザーデータをjson形式で管理して複数のユーザーの認証ができるようにします
ファイル構成
今回のファイル構成は以下の通りです。
---|--public |
|--main.html
|--style.css
|--main.js
|--Server.js
|--userdata.json
準備
まず、以下のコマンドをcmdで実行して、ログインサーバーのフォルダーに移動ください
cd C:\Users\<Your_Username>\Downloads\<Your_Project_FolderName>
※仮のpathです。実行するときはC:~の部分を作成したフォルダのpathに変更してください
次に、以下のコマンドを入力します
npm install express cors fs
※node.jsをインストールしていない方は、こちらからnode.jsをダウンロードしてください。
コピペ
以下のコードをコピペしましょう
サーバー側のjavascript
Server.js
const express = require('express');
const cors = require('cors');
const fs = require('fs');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'public')));
app.use(cors());
app.use(express.json());
app.post('/login', (req, res) => {
const name = req.body.User;
const pass = req.body.Password;
if (!name || !pass) {
return res.status(400).json({ error: 'ユーザー名またはパスワードが不足しています。' });
}
try {
const userdata = fs.readFileSync('Userdata.json', 'utf-8');
const ParseData = JSON.parse(userdata);
const Fdata = ParseData.find(Udata => Udata.username === name && Udata.Password === pass);
if (Fdata) {
console.log('認証成功:', Fdata);
res.json(Fdata);
} else {
res.status(401).json({ error: '認証に失敗しました。ユーザー名またはパスワードが正しくありません。' });
}
} catch (error) {
console.error('エラーが発生しました:', error.message);
res.status(500).json({ error: 'サーバーエラーが発生しました。' });
}
});
app.post('/signup', (req, res) => {
const name = req.body.User;
const pass = req.body.Pass;
const age = req.body.age;
if (!name || !pass || !age) {
return res.status(400).json({ error: 'ユーザー名またはパスワードまたは年齢等の情報が不足しています。' });
}
try {
const Fdata = fs.readFileSync('Userdata.json', 'utf8');
const ParseData = JSON.parse(Fdata);
if (ParseData.find(Users => Users.username === name)) {
return res.status(409).json({ error: "既に同じユーザー名が存在しています" });
}
// 新しいユーザー情報の作成
const NewUserConfig = {
username: name,
Password: pass,
age: age
};
// ユーザーデータに追加して保存
ParseData.push(NewUserConfig);
fs.writeFileSync('Userdata.json', JSON.stringify(ParseData, null, 2), 'utf8');
res.json({ message: "サインアップが完了しました。" });
} catch (error) {
console.error('エラーが発生しました:', error.message);
res.status(500).json({ error: 'サーバーエラーが発生しました。' });
}
});
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'main.html'));
});
app.listen(3000, () => {
console.log('server running on port 3000.');
});
html
main.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="load.css">
<link rel="stylesheet" href="style.css">
<title>ログイン</title>
</head>
<body>
<div id="Domcontainer"></div>
<script src="script.js"></script>
</body>
</html>
クライアント側のjs
script.js
function afterAddEvent(EType) {
switch(EType) {
case "login":
document.getElementById("loginForm").addEventListener("submit", function(event) {
event.preventDefault();
fetch('/login', {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
User: document.getElementById('email').value,
Password: document.getElementById('password').value
})
})
.then(response => response.json())
.then(data => {
if (data.error) {
ChangeHTML('error');
setTimeout(() => {
document.getElementById('ErrorContent').textContent = data.error;
}, 500);
return;
}
ChangeHTML('Home');
setTimeout(() => {
document.getElementById('Main-Content').textContent = `Welcome back ${data.username}`;
document.getElementById('HomeMain').innerHTML = `
<p>mailaddress: ${data.username}</p>
<p>age: ${data.age}</p>`;
}, 500);
})
.catch(error => {
console.error("Error:", error);
ChangeHTML('error');
setTimeout(() => {
document.getElementById('ErrorContent').textContent = "FetchError: サーバーとの通信に失敗しました。";
}, 500);
});
});
document.getElementById("passShow").addEventListener("change", function() {
const passwordInput = document.getElementById("password");
passwordInput.type = this.checked ? "text" : "password";
});
break;
case "signup":
document.getElementById("signupForm").addEventListener("submit", function(event) {
event.preventDefault(); // デフォルトのフォーム送信を防ぐ
// サインアップのデータ送信
fetch('/signup', {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
User: document.getElementById('email').value,
Pass: document.getElementById('password').value,
age: document.getElementById('age').value
})
})
.then(response => response.json())
.then(data => {
if (data.error) {
ChangeHTML('error');
setTimeout(() => {
document.getElementById('ErrorContent').textContent = data.error;
}, 500);
return;
}
// サインアップ成功時の処理
ChangeHTML('login');
setTimeout(() => {
document.getElementById('Main-Content').textContent = "アカウント作成が完了しました。ログインしてください。";
}, 500);
})
.catch(error => {
console.error("Error:", error);
ChangeHTML('error');
setTimeout(() => {
document.getElementById('ErrorContent').textContent = "FetchError: サーバーとの通信に失敗しました。";
}, 500);
});
});
break;
// 他のケース...
}
}
window.onload = ChangeHTML('login');
function ChangeHTML(HTMLtype) {
let NewHTML = "";
switch(HTMLtype) {
case "login":
NewHTML = `
<div class="login-container">
<h1>ログイン</h1>
<form id="loginForm">
<input type="text" id="email" placeholder="メールアドレス" required>
<input type="password" id="password" placeholder="パスワード" required>
<br><input type="checkbox" id="passShow"> パスワードを表示
<button class="login-button" type="submit">次へ</button>
</form>
<p>アカウントをお持ちでないですか? <a href="#" onclick="ChangeHTML('signup')">作成する</a></p>
</div>
`;
setTimeout(() => {
afterAddEvent("login");
}, 500);
break;
case "signup":
NewHTML = `
<div class="signup-container">
<h1>サインアップ</h1>
<form id="signupForm">
<input type="text" id="email" placeholder="メールアドレス" required>
<input type="password" id="password" placeholder="パスワード" required>
<input type="number" id="age" placeholder="年齢を入力">
<button class="login-button" type="submit">次へ</button>
</form>
<p>既にアカウントをお持ちですか? <a href="#" onclick="ChangeHTML('login')">ログインする</a></p>
</div>
`;
setTimeout(() => {
afterAddEvent("signup");
}, 500);
break;
case "error":
NewHTML = `
<div class="login-container">
<h1>Error</h1>
<p id="ErrorContent"></p>
</div>`;
break;
case "Home":
NewHTML = `
<div class="login-container">
<h1>Home</h1>
<h1 id="Main-Content"></h1>
<div id="HomeMain"></div>
</div>
`;
break;
default:
NewHTML = `
<div class="error-container">
<h1>Error</h1>
<p>エラー:ページが存在しないよ!</p>
<p>error: page is not found!</p>
</div>
`;
}
document.getElementById('Domcontainer').innerHTML = NewHTML;
}
window.onload = ChangeHTML('login');
css
style.css
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f5f5f5;
}
.login-container {
width: 360px;
padding: 40px;
background-color: #fff;
border: 1px solid #ddd;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
text-align: center;
}
.login-container img {
width: 75px;
margin-bottom: 20px;
}
h1 {
font-size: 24px;
color: #202124; /* テキスト色 */
margin: 0 0 20px;
}
p {
font-size: 14px;
color: #5f6368; /* 説明文の色 */
margin: 0 0 20px;
}
input[type="email"],
input[type="text"],
input[type="password"],
input[type="number"] {
width: 100%;
padding: 12px;
margin: 8px 0;
border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box;
}
.button-container {
margin-top: 20px;
}
.login-button {
width: 100%;
padding: 10px;
background-color: #0078d4;
color: #fff;
border: none;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
}
.login-button:hover {
background-color: #005ea1; /* ホバー時の色 */
}
.forgot-email,
.create-account {
font-size: 14px;
color: #1a73e8;
text-decoration: none;
display: inline-block;
margin-top: 20px;
}
.forgot-email:hover,
.create-account:hover {
text-decoration: underline;
}
.error-message {
color: red;
margin-top: 15px;
font-size: 14px;
}
json(確認したら自動的に生成されませんでした)
Userdata.json
[
]
説明(?)
今回はfsを使って、複数ユーザーのログインを実装しています
ちなみに、Userdata.jsonを削除した状態でやると、サーバーでエラーが起きます
最後に
いかがだったでしょうか?今回はfsとexpressを使って、ログイン機能を作りました。ちなみに、今回もsignupの処理がうまくいかなかったので、ChagtGPTに修正してもらいました。
それではまたお会いしましょう!