Axum과 Diesel,postgresSQL을 사용하여 Login 구현 (2)

Axum

Posted by Hebi on April 25, 2024

Router

전 페이지

Axum과 Diesel,postgresSQL을 사용하여 Login 구현 (1)

Router구성하기

전 에 이어서 시작합니다. router라는 폴더를 생성해줍니다. router에는 특정경로에 들어갓을떄 실행되는 함수를 만들어 줄것입니다. 그전에 앞서 index html을 꾸며줄것입니다. 로그인을 하려면 두개의 input과 하나의 button이 필요합니다. body에 코드를 추가해줍니다.

1
2
3
4
5
6
7
8
9
   <div class="login-container">
        <h1>Login</h1>
        <label for="id">ID</label>
        <input id="id" type="text" />
        <label for="pw">Password</label>
        <input id="pw" type="password" value="" />
        <button onclick="login_btn()">Login</button>
    </div>

css에는 다음을 추가해줍니다.꾸미는 것에대한 소개는 생략을 하고 진행하겟습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
    body {
        font-family: Arial, sans-serif;
        background-color: #f0f0f0;
        margin: 0;
        padding: 0;
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
    }
    .login-container {
        width: 300px;
        background-color: #ffffff;
        padding: 20px;
        border-radius: 5px;
        box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    }
    .login-container h1 {
        text-align: center;
        color: #333;
        margin-bottom: 20px;
    }
    .login-container label {
        display: block;
        margin-bottom: 5px;
        color: #555;
    }
    .login-container input[type="text"], .login-container input[type="password"] {
        width: calc(100% - 40px);
        padding: 10px;
        margin-bottom: 20px;
        border: 1px solid #ccc;
        border-radius: 3px;
        box-sizing: border-box;
    }
    .login-container button {
        width: 100%;
        padding: 10px;
        border: none;
        background-color: #007bff;
        color: #fff;
        cursor: pointer;
        border-radius: 3px;
        box-sizing: border-box;
    }
    .login-container button:hover {
        background-color: #0056b3;
    }

css와 html코드를 추가하고 나면 다음과 같이 모습이 되어 있을것입니다.

그다음 index에서 서버로 id와 password를 보냇을때 로그인이 되게 만들려면 먼저 서버로 Json형태로 데이터를 보내야 합니다. body 최하단에 다음 스크립트를 생성해줍니다.id와 pw의 value를 받아서 http://localhost:3000/login로 보냅니다 login router은 아직 생성이 안됬습니다. 보낼때는 json 형태로 보내며 서버에서 보내는 결과값이 true이면 success page로 false이면 Error페이지로 이동합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<script>
        function login_btn() {
            let id = document.getElementById("id");
            let pw = document.getElementById("pw");
            const data = { id: id.value, pw: pw.value };
            fetch('http://localhost:3000/login', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(data)
            })
                .then(response => {
                    if (!response.ok) {
                        throw new Error('Network response was not ok');
                    }
                    return response.json();
                })
                .then(data => {
                    if (data.result == true) {
                        location.href = 'http://localhost:3000/success'

                    } else {
                        location.href = 'http://localhost:3000/error'

                    }
                    console.log(data);
                })
                .catch(error => {
                    console.error('There has been a problem with your fetch operation:', error);
                });
        }
    </script>

다음은 간단한 success페이지와 error페이지를 작성합니다.

  • Error Page ```html <!DOCTYPE html>
Document

Error

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- login sucess page
```html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <h1>Login</h1>
 
   
</body>

</html>

router폴더에는 pages.rs 와 auth.rs mod.rs를 생성해줍니다 먼저 mod.rs는

1
2
pub mod auth;
pub mod pages;

를 저장하며

lib.rs 에 추가해줍니다.

1
pub mod router;
  • run 함수에는 route에 /login 과 성공했을떄 이동할 /success 와 실패했을떄 이동할 /error 를 추가해줍니다. get이나 post 안에 login은 pages.rs와 auth.rs에서 불러온 함수들입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
pub async fn run() {
    let app = Router::new()
        .route("/", get(index))
        .route("/login", post(login))
        .route("/success", get(success))
        .route("/error", get(error));

    let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
        .await
        .unwrap();
    println!("listening on {}", listener.local_addr().unwrap());
    axum::serve(listener, app).await.unwrap();
}

먼저 model 폴더를 생성한후 auth 모델을 정해줍니다.현재 id와 Pw만 받을것이기때문에 model 폴더에 auth.rs에 LoginUser를 정의해줍니다.

1
2
3
4
5
6
7
8
use serde::Deserialize;

#[derive(Deserialize, Debug)]
pub struct LoginUser {
    pub id: String,
    pub pw: String,
}

그다음 먼저 router/auth.rs로 가서 login 함수를 생성해줍니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use crate::model::auth::LoginUser;
use axum::response::Json;
use serde_json::{json, Value};

pub async fn login(Json(user): Json<LoginUser>) -> Json<Value> {
    println!("{}", user.id);
    println!("{}", user.pw);
    if user.id == "abcd" && user.pw == "1234" {
        Json(json!({ "result": true }))
    } else {
        Json(json!({ "data": false }))
    }
}

login함수는 model/auth.rs에서 불러온 LoginUser를 Json형태로 프론트서버에서 받아오며 id가 abcd , pw 가 1234 가 맞으면 로그인 성공이라 판단하여 프론트 서버에 ture를 보내며 틀리면 false를 보냅니다.db에 저장하여 로그인하는 것은 다음장에서 이어서 합니다. 지금까지 만든 폴더는 다음과 같은 구조를 띄어야 합니다.

로그인하는 결과는 다음과 같습니다.성공하면 success페이지 실패하면 error페이지로 넘어가게됩니다.

전체코드