아두이노프로세싱 프로그래밍

라즈베리 파이 Flask 와이파이 마이크로 웹서버 LOGIN 시스템 코딩

coding art 2017. 8. 1. 20:12
728x90

아두이노 코딩의 소중한 경험을 시작하고 싶으신가요?

이 책에서 해답을 찾으세요.

교보문고에서 판매중입니다



_______________________________________________________upto here, commercial!______________________



지금까지는 클라이언트로부터 request 와  단순한 on OFF 명령을 전달하는 수준의 웹서버를 코딩하였다. 하지만 웹서버는 사용자가 사용자 ID 와 Password 에 의해 Login 하여 사용하는 웹서버로 코딩해야 할 필요성을 지적한다.

그림의 웹 브라우저 로그인 화면을 참조하자. username 과 password 는 각각 “admin” 과 “password” 로 약속해 놓고 코딩하기로 한다.

회원 등록 데이타 베이스를 이용하여면 mySQL 을 끌여들여야 하기 때문에 여기서는 간단하게 사용자명과 비빌번호를 정해 놓고 혼자 사용하는 것으로 가정하자.

일단 login 이 성공하면 파이선 플라스크 코드에서 지정하는 홈 화면으로 이동 후 logout  버튼을 클릭하면 다시 login  화면으로 돌아오도록 코딩하자.






파이선 실행 파일에서 Flask 모듈을 불러 들여 flash, redirect, render_templte, request, session, abord를 포함하는 클라스들을 세팅한다.


flash는 Java Script 의 클릭에 대한 메시지를 보여 주는 역할을 비슷하게 담당한다.  이 클라스 각각을 잘 이해하기 위해서는 별도의 예제가 필요할 수도 있으므로 그때그때 소개하도록 한다.

Flask 와이파이 코드의 기본 골격은 app = Flask(__name__)로 시작해서 몇 개의 필수적인 @app.route(⚫⚫⚫) 들과 함께 if__name__==“__main__” 으로 끝맺는다.



Login 웹화면 홈의 상위 디렉토리인 @app.route(‘/’)는 home() 이라는 함수로 정의한다. 즉 로그인 세션에서 ‘logged_In’ 이라는 문자 메시지를 접수하지 못하면 다시 ‘login.html’ HTML 파일을 실행시키게 된다. 그렇지 않은 경우 즉 제대로 입력이 되었다면/logout 디렉토리에서 “Hello Boss!” 라는 메시지와 Logout 하이퍼링크를 웹 화면에 출력한다.

반면에 ‘/login’ 디렉토리에서 로그인 과정의 정보는 @app.route(‘/login’)에서 정의된 do_admin_login() 함수를 통해 웹 로그인 화면에서 입력된 사용자 명과 비밀번호가 POST 방식에 의해 파이선 실행 코드에 전달된다.
login.html 파일에서 form  태그에 의해 입력된 이들 정보는  클라스 명령 request.form[⚫⚫⚫]을 사용하여 파이선 실행 코드에서 수신가능하며 if 문에서 붙박이로 주어진 사용자명 ‘admin’ 과 비밀번호 ‘password’ 를 비교해 볼 수 있다. 비교 결과가 참이면 session[‘logged_In]을 True 로 두고 아니면 ’wrong password’ 메시지와 함께 home(0 으로 돌려주게 된다. 

제대로 로그인이 되면 @app.route(‘/’)에서  @app.route(‘/logout’) 디렉토리로 옮겨 “Hello Boss!” 라는 메시지와 Logout 하이퍼링크를 웹 화면에 출력한다. 만약 이 하이퍼링크를 클릭하면 원래의 login  홈 화면으로 되돌아오게 된다.







Flask 와이파이 코드의 마지막 부분인 if__name__==“__main__” 의 app.run()에서 port=4000 즉 포트 번호를 4000 으로 지정할 경우 라즈베리 파이에서 127.0.0.1:5000 을 사용하지는 못하며 http://localhost:4000 을 사용해야 한다.

무선 공유기가 설치된 PC에서 사용하려면 이 번호를 5000으로 수정해야 한다. 아울러 PC 웹 브라우저에서 라즈베리 파이에 할당되어 있는 가상 ip에 :5000 을 추가하여 request를 발생시키면 된다.

파이선 실행 코드 l.py가 부르는 login.html에서 맨 첫줄에





<link rel="stylesheet" href="/static/style.css" type="text/css"> 태그를 살펴보자. <link rel=⚫⚫⚫> 태그는 Login HTML 화면을 어느 정도 꾸밀 수 있도록 별도로 static  디렉토리에 CSS 파일을 저장해 두고 불러 쓰게 된다. Flask 모듈 파이선 코딩에서는 파이선 실행 코드가 들어 있는 디렉토리에 HTML 파일을 저장해 두는 templates 디렉토리 외에 static 이란 명칭의 디렉토리를 두어 HTML CSS 파일을 저장하도록 하고 있다.


파이선 실행 코드와 상호 통신하게 되는 HTML 코드는 다음과 같이 <> 대신에 {%...%} 태그를 사용하는 구조로서 단순 body 가 아닌 block body 가 사용되며 끝 부분에 반드시 endblock 으로 마쳐야 한다.

{% block body %}
⚫⚫⚫
{% endblock %}

⚫⚫⚫에 해당하는 코드 내용 물 중에서  if 문 처리를 해야 하면 역시 {%...%} 태그(?)를 사용해야 할 필요가 있다.
{% if session['logged_in'] %}
<p>You're logged in already!</p>
{% else %}
순수 HTML 코드
{% endif %}

{% else %}에 이어지는 순수 HTML 코드는 <form>태그에서 <input> 태그를 사용하여 사용자 ID 와 비밀번호를 입력하고 Log in 버튼 키를 눌러 POST 방식으로 파이선 실행 코드로 보내는 코드이au 아래를 참조하기 바란다.


    
현재의 LOGIN 코드는 홈페이지에서 사용자명과 비밀번호를 입력해서 로그인하게 되면 막바로 Logout 하이퍼링크가 있는 /logout  디렉토리로 이동하고 로그아웃하면 다시 홈페이지로 되돌아 오는 단순한 구조이다. 따라서 로그인 후 응용 프로그램이 제공되는 웹 페이지로 넘어가서 여러 가지 작업을 한 후에 로그아웃하는 구조로 코드를 수정할 필요가 있다.


l.py

from flask import Flask

from flask import Flask, flash, redirect, render_template, request, session, abort

import os

 

app = Flask(__name__)

 

@app.route('/')

def home():

    if not session.get('logged_in'):

        return render_template('login.html')

    else:

        return "Hello Boss!  <a href='/logout'>Logout</a>"

 

@app.route('/login', methods=['POST'])

def do_admin_login():

    if request.form['password'] == 'password' and request.form['username'] == 'admin':

        session['logged_in'] = True

    else:

        flash('wrong password!')

    return home()

 

@app.route("/logout")

def logout():

    session['logged_in'] = False

    return home()

 

if __name__ == "__main__":

    app.secret_key = os.urandom(12)

    app.run(debug=True,host='0.0.0.0', port=4000)


style.css

* {
box-sizing: border-box;
}
 
*:focus {
	outline: none;
}
body {
font-family: Arial;
background-color: #3498DB;
padding: 50px;
}
.login {
margin: 20px auto;
width: 300px;
}
.login-screen {
background-color: #FFF;
padding: 20px;
border-radius: 5px
}
 
.app-title {
text-align: center;
color: #777;
}
 
.login-form {
text-align: center;
}
.control-group {
margin-bottom: 10px;
}
 
input {
text-align: center;
background-color: #ECF0F1;
border: 2px solid transparent;
border-radius: 3px;
font-size: 16px;
font-weight: 200;
padding: 10px 0;
width: 250px;
transition: border .5s;
}
 
input:focus {
border: 2px solid #3498DB;
box-shadow: none;
}
 
.btn {
  border: 2px solid transparent;
  background: #3498DB;
  color: #ffffff;
  font-size: 16px;
  line-height: 25px;
  padding: 10px 0;
  text-decoration: none;
  text-shadow: none;
  border-radius: 3px;
  box-shadow: none;
  transition: 0.25s;
  display: block;
  width: 250px;
  margin: 0 auto;
}
 
.btn:hover {
  background-color: #2980B9;
}
 
.login-link {
  font-size: 12px;
  color: #444;
  display: block;
	margin-top: 12px;
}


login.html

<link rel="stylesheet" href="/static/style.css" type="text/css">

{% block body %}

{% if session['logged_in'] %}

<p>You're logged in already!</p>

{% else %}

 

 

<form action="/login" method="POST">

<div class="login">

<div class="login-screen">

<div class="app-title">

<h1>Login</h1>

</div>

 

<div class="login-form">

<div class="control-group">

<input type="text" class="login-field" value="" placeholder="username" name="username">

<label class="login-field-icon fui-user" for="login-name"></label>

</div>

 

<div class="control-group">

<input type="password" class="login-field" value="" placeholder="password" name="password">

<label class="login-field-icon fui-lock" for="login-pass"></label>

</div>

 

                <input type="submit" value="Log in" class="btn btn-primary btn-large btn-block" >

   <br>

</div>

</div>

</div>

</form>

 

{% endif %}

{% endblock %}