1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

フロントのみで簡単なログイン機能を作る

Last updated at Posted at 2024-09-27

はじめに

javascriptとhtml、cssを使って簡単なログイン機能を書いてみました。

ファイル構成

login |--html
      |     |
      |     |--login.html
      |     |--profile.html
      |     |--create-account.html
      | 
      |--app.js
      |  
      |--styles.css

HTML

login.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ログイン</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="container">
        <h2>ログイン</h2>
        <form id="loginForm">
            <input type="email" id="email" placeholder="メールアドレス" required>
            <input type="password" id="password" placeholder="パスワード" required>
            <button type="submit">ログイン</button>
        </form>
        <p>アカウントをお持ちでない方は <a href="create-account.html">新規アカウント作成</a></p> <!-- ここを修正 -->
    </div>

    <script src="app.js"></script>
</body>
</html>

profile.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ユーザープロフィール</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="container">
        <h2>ようこそ、<span id="displayName"></span>さん</h2>
        <img id="displayIcon" alt="ユーザーアイコン" style="width:100px;height:100px;">
    </div>

    <script src="app.js"></script>
</body>
</html>

create-account.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>新規アカウント作成</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="container">
        <h2>新規アカウント作成</h2>
        <form id="accountForm">
            <input type="email" id="newEmail" placeholder="メールアドレス" required>

            <input type="password" id="newPassword" placeholder="パスワード" required>

            <input type="text" id="username" placeholder="ユーザー名" required>

            <input type="file" id="userIcon" accept="image/jpeg" required>

            <button type="submit">アカウント作成</button>
        </form>
    </div>

    <script src="app.js"></script>
</body>
</html>

CSS

styles.css

/* 基本設定 */
body {
    font-family: 'Poppins', sans-serif;
    background-color: #f5f5f5;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}

/* コンテナのスタイル */
.container {
    width: 100%;
    max-width: 350px;
    padding: 30px;
    background-color: white;
    border-radius: 10px;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
    text-align: center;
}

/* 見出しスタイル */
h2 {
    margin-bottom: 20px;
    font-size: 1.5rem;
    color: #333;
    font-weight: 600;
}

/* 入力フィールドのスタイル */
input[type="email"],
input[type="password"],
input[type="text"],
input[type="file"] {
    width: 80%;
    max-width: 280px;
    padding: 12px 15px;
    margin: 10px 0;
    border: 2px solid #ddd;
    border-radius: 8px;
    background-color: #f9f9f9;
    font-size: 1rem;
    transition: border 0.3s, background-color 0.3s;
}

/* フォーカス時のスタイル */
input[type="email"]:focus,
input[type="password"]:focus,
input[type="text"]:focus {
    border-color: #b654c5;
    background-color: white;
    outline: none;
    box-shadow: 0 0 5px rgba(0, 123, 255, 0.5);
}

/* ボタンのスタイル */
button {
    width: 80%;
    max-width: 280px;
    padding: 12px;
    background-color: #b654c5;
    color: white;
    font-size: 1rem;
    font-weight: 600;
    border: none;
    border-radius: 8px;
    cursor: pointer;
    transition: background-color 0.3s, box-shadow 0.3s;
}

/* ボタンホバー時のエフェクト */
button:hover {
    background-color: #b654c5;
    box-shadow: 0 4px 12px rgba(0, 91, 179, 0.2);
}

/* リンクのスタイル */
p a {
    color: #b654c5;
    text-decoration: none;
    font-weight: 600;
    transition: color 0.3s ease;
}

p a:hover {
    color: #b654c5;
}

/* ユーザーアイコンのスタイル */
#displayIcon {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    object-fit: cover;
    margin-top: 10px;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}

/* レスポンシブ設定 */
@media (max-width: 768px) {
    .container {
        width: 90%;
    }
}

JavaScript

app.js

// ログインフォームの処理
if (document.getElementById('loginForm')) {  //HTMLの'loginForm'を確認
    document.getElementById('loginForm').addEventListener('submit', function(e) {  //'loginForm'があった場合のイベントを追加
        e.preventDefault();                 //デフォルトの動作をキャンセルする
        const email = document.getElementById('email').value;  //ユーザーが入力したemailを取得
        const password = document.getElementById('password').value;  //ユーザーが入力したpasswordを取得

        const storedEmail = getCookie('email');    //クッキーに保存されたemailを取得
        const storedPassword = getCookie('password');    //クッキーに保存されたpasswordを取得

        if (email === storedEmail && password === storedPassword) {   //ユーザーが入力したemailとpasswordがクッキーに保存されている情報と一致しているか確認
            window.location.href = 'profile.html';  //一致している場合profile.htmファイルに移動
        } else {
            alert('Incorrect email or password');  //一致していない場合アラートが表示
        }
    });
}

// アカウント作成フォームの処理
if (document.getElementById('accountForm')) {    //HTMLの'accountForm'を確認
    document.getElementById('accountForm').addEventListener('submit', function(e) {     //'accountFormがあった場合のイベントを追加
        e.preventDefault();              //デフォルトの動作をキャンセルする

        const email = document.getElementById('newEmail').value;    //ユーザーが入力したemailを取得
        const password = document.getElementById('newPassword').value;    //ユーザーが入力したpasswordを取得
        const username = document.getElementById('username').value;    //ユーザーが入力したユーザー名を取得
        const userIcon = document.getElementById('userIcon').files[0];    //ユーザーが入力したアイコンを取得

        if (userIcon && userIcon.type === 'image/jpeg') {    //ユーザーがアップロードしたアイコンがjpegか確認
            const reader = new FileReader();      //画像を読み込む
            reader.onload = function(e) {     //読み込みが終えたら実行する処理(クッキーに保存)
                setCookie('email', email, 7);     //ユーザーが入力したemailをクッキーに保存
                setCookie('password', password, 7);     //ユーザーが入力したpasswordをクッキーに保存
                setCookie('username', username, 7);     //ユーザーが入力したをユーザー名クッキーに保存
                setCookie('userIcon', e.target.result, 7);     //ユーザーが入力したアイコンをクッキーに保存
                alert('Account created successfully');     //アカウントが作成されたことを表示
                window.location.href = 'login.html';     //アカウント作成後login.htmlページにに移動
            };
            reader.readAsDataURL(userIcon);     //ユーザーがアップロードした画像データを使えるようにする
        } else {
            alert('Please upload a JPEG image');     //ユーザーがアップロードしたアイコンがjpegではなかったに場合エラー表示する
        }
    });
}

// プロファイルページでユーザー情報を表示
if (window.location.pathname.includes('profile.html')) {     
    const username = getCookie('username');     //クッキーに保存されたユーザー名を取得
    const userIcon = getCookie('userIcon');     //クッキーに保存されたアイコンを取得

    if (username && userIcon) {     //ユーザー名とアイコンが存在するか確認
        document.getElementById('displayName').textContent = username;     //クッキーから取得したユーザー名を表示
        document.getElementById('displayIcon').src = userIcon;     //クッキーから取得したアイコンを表示
    } else {
        window.location.href = 'login.html';     //クッキーに情報がない場合'login.html'ページに移動
    }
}

// Cookieを設定する関数
function setCookie(name, value, days) {     //クッキーを設定するための関数(ユーザー名, 値, 保存期間)
    const date = new Date();     //Dateオブジェクトを作成
    date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));     //クッキーの有効期限を設定
    const expires = "expires=" + date.toUTCString();     //クッキーの有効期限をexpiresに変換 //日時を文字列に変換
    document.cookie = name + "=" + value + ";" + expires + ";path=/";     //クッキーを作成(名前、値、有効期限、サイト全体で有効であることを指定)
}

// Cookieを取得する関数
function getCookie(name) {     //クッキーの名前を引数として受け取る
    const nameEQ = name + "=";     //クッキーの名前を作る
    const ca = document.cookie.split(';');     //クッキー全体を分割
    for (let i = 0; i < ca.length; i++) {     //各クッキーをループで確認
        let c = ca[i];
        while (c.charAt(0) === ' ') c = c.substring(1, c.length);
        if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);     //クッキー名が一致するか確認
    }     //ループが終えてもクッキーが届かなかった場合nullを返す

    return null;
}

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?