📝 인증(Authentication)

인증은 유저의 identification을 확인하는 절차이다. 한 마디로, 유저의 아이디와 비밀번호를 확인하는 절차다.

인증을 하기 위해선 먼저, 유저의 아이디와 비밀번호를 생성할 수 잇는 기능도 필요하다.

우리가 생각하는 로그인 절차는 생각해보자.

1. 회원가입 : 아이디와 비밀번호를 생성한다.

  • 이때, 비밀번호는 암호화 저장한다.

2. 로그인 : 아이디와 비밀번호를 입력한다.

  • 입력한 비밀번호를 암호화 한 후, DB에 저장된 암호화 비밀번호와 비교한다.

3. 일치하면 로그인 성공, 일치하지 않으면 에러가 발생한다.

4. 로그인이 성공되면 access_tocken을 클라이언트에게 전송한다.

5. 유저는 로그인 성고 후 다음부터는 access_tocken을 첨부해서, request를 서버에 전송한다.

 

💡 비밀번호 암호화

유저의 비밀번호는 절대 그대로 DB에 저장되지 않는다. 만일 DB가 해킹 당할 경우, 그대로 유출되기 때문이다.
따라서, 유저의 비밀번호는 반드시 암호화하여 저장해야 한다. 그럴 경우 DB가 해킹 당하더라도 그대로 노출되지 않기 때문이다.

💡 허가(Authorization)

허가는 유저가 요청하는 request를 실행할 수 있는 권한이 있는 유저인가를 확인하는 절차이다.
예를 들어 해당 유저는 고객 정보를 볼 수 있지만, 수정할 권한은 없는 경우이다.

 

📝 Flask 로그인 구현하기

# 1번을 해보세요!
from flask import Flask, request, render_template, session, url_for, redirect

app = Flask(__name__)
app.secret_key = 'super secret key'
app.config['SESSION_TYPE'] = 'filesystem'
userinfo = {'Elice': '1q2w3e4r!!'}


@app.route("/")
def home():
    if session.get('logged_in'):
        return render_template('loggedin.html')
    else:
        return render_template('index.html')


@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        name = request.form['username']
        password = request.form['password']
        try:
            if (name in userinfo):
                #2번을 해보세요!
                session["logged_in"] = True
                    #3번을 해보세요!
                return render_template('loggedin.html')
                    #4번을 해보세요!
            else:
                return '비밀번호가 틀립니다.'
            return '아이디가 없습니다.'
        except:
            return 'Dont login'
    else:
        return render_template('login.html')


@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        #4번을 해보세요!
        name = request.form['username'] 
        password = request.form['password']
        userinfo[name] = password
        
        return redirect(url_for('login'))
    else:
        return render_template('register.html')


@app.route("/logout")
def logout():
    session['logged_in'] = False
    return render_template('index.html')
    
if __name__ == '__main__':
    app.run()
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>HTML for python flask</title>
</head>

<body>
        <p>로그인이 필요한 서비스입니다.</p>
        <a href= "login">로그인창으로</a><br>
        <a href= "register">회원가입</a>
</body>
</html>


<!-- loggedin.html -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>HTML for python flask</title>
</head>

<body>
        <form action = "" method="post">
        <p>로그인 성공 페이지</p>
        <a href= "/logout">로그아웃</a>
        </form>
</body>
</html>


<!-- login.html -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>HTML for python flask</title>
</head>

<body>
    <form action = "" method="post">
        <p>name : <input type="text" name = "username"></p>
        <p>password : <input type="password"  name = "password"></p>
        <p>이름과 비밀번호를 입력하고 로그인버튼을 누르세요.<br><input type = "submit" value = "로그인"/> </p>
    </form>
</body>
</html>


<!-- register.html -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>HTML for python flask</title>
</head>

<body>
    <form action = "" method="post">
        <p>name : <input type="text" name = "username"></p>
        <p>password : <input type="password" name = "password"></p>
        <p>이름과 비밀번호를 입력하고 생성버튼을 누르세요.<br> <input type = "submit" value = "생성"/> </p>
    </form>
</body>
</html>

[ 출처 : elice ]

 

📝 로깅

로깅은 프로그램이 작동할 때 발생하는 이벤트를 추적하는 행위이다.
프로그램의 문제들을 파악하고 유지보수하는데 사용되고, 로깅을 통해 발생한 에러를 추적 가능하다.

운영 중인 웹 서비스에서 문제가 발생했을 경우, 해당 문제의 원인을 파악하려면 문제가 발생했을 때의 정보가 필요하다.
이런 정보를 얻기 위해서 중요한 기능의 실행되는 부분에 적절한 로그(log)를 남겨야 한다.
일반적인 로그 기록의 이점은 다음과 같다.

  • 로그는 성능에 관한 통계와 정보를 제공할 수 있다.
  • 로그는 재현하기 힘든 버그에 대한 유용한 정보를 제공할 수 있다.
  • 설정이 가능할 때, 로그는 예기치 못한 특정 문제들을 디버그하기 위해 그 문제들을 처리하도록  코드를  수정하여 다시 적용하지 않아도, 일반적인 정보를 저장할 수 있다.

💡 로깅 레벨(Loggin Level)

다음 순서로 로깅이 된다.

DEBUG < INFO < WARNING < ERROR < CRITICAL

  • DEBUG : 상세한 정보
  • INFO : 일반적인 정보
  • WARNING : 예상치 못하거나, 가까운 미래에 발생할 문제
  • ERROR : 에러 로그, 심각한 문제
  • CRITICAL : 프로그램 자체가 실행되지 않을 수 있는 문제

파이썬 로거 레벨 설정에 따라, 하위 레벨은 출력되지 않는다.
기본 로거 레벨 세팅은 WARNING 이다. 때문에  설정 없이는 INFO, DEBUG를 출력할 수 없다.

💡 python logger

기본적으로 다음 로깅 이력은 남기는 것이 좋다.

  • 서버 시작 로그
  • 서버 포트 번호
  • 함수 호출
  • 데이터의 입출력
#예시 코드
import logging 

if __name__ : '__main__': 
    logging.info("hello elice!")

위 코드로 실행하면, "hello elice!" 가 출력되지 않는다. 위에서 언급했듯이, 로깅의 기본 세팅은 WARNING이기 때문
그렇다면 어떻게 하면 "hello elice!" 가 출력이 될까 ?  아래 코드와 같이 설정하면 출력된다.

import logging 

if __name__ : '__main__': 
    logger = logging.getLogger() 
    logger.setlevel(logging.DEBUG) 	# 로깅 기본세팅 WARNING -> DEBUG로 변경
    logger.info("hello elice!")

 

📝 Flask logger

플라스크는 0.3 버전부터 logger를 플라스크 내부에서 제공하기 시작했다. 😮
(플라스크에서 기본적으로 제공하는 로깅을 제외하고, 일반 python logging을 사용해도 무방하다. )

# 레벨에 따른 함수가 이미 있어서, 따로 로깅레벨 설정을 안해도 된다.

from flask import Flask 
app = Flask(__name__) 
if __name__ == '__main__': 

    app.logger.info("test") 
    app.logger.debug("debug test") 
    app.logger.error("error test") 
    app.run()

 

💡 Flask logger 구현

from flask import Flask, render_template

app = Flask(__name__)

# .errorhandler(에러코드) : flask 내부에 기본적으로 있는 에러 핸들러
# 특정 에러에 대하여 errorhandler를 사용하면, 해당 에러가 발생했을 때 매칭된다.
@app.errorhandler(404)
def page_not_found(error):
    app.logger.error(error)
    return "페이지를 찾을 수 없습니다."

@app.route("/")
def hello_elice():
    return "Hello world!"

if __name__ == '__main__':
    app.run()

[ 출처 : elice ]

 

728x90
반응형

📝 렌더링 템플릿

렌더링(Rendering) : 마크업 언어를 브라우저(Client)에 보여주기 위한 과정

플라스크 내에서 html 파일을 사용해 웹 사이트를 제작할 수 있다. 이 때 사용하는 것이 렌더링 템플릿이다.
html 코드들을 플라스크내에 사용하는 것보다 파일을 따로 만들어 라우팅하는 방법이 유지보수에서 이롭다.

플라스크는 render_template( )을 이용해 html 파일을 렌더링하여 브라우저에 보여줄 수 있습니다.

from flask import render_template

@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
    return render_template('hello.html', name=name)

hello 함수의 URL에 접근할 때, hello.html을 반환하며 해당 html 파일의 매개변수 name에 함수의 매개변수인 name을 전달한다.

 

📝 Jinja2

렌더링 템플릿을 통해 화면을 출력할 때 html에서는 아래와 같은 Jinja2 문법으로 해당 내용을 띄울 수 있습니다.

{% for row in rows %}
<tr>
    <td>{{ loop.index }}</td>
    <td>{{ row[0] }}</td>
    <td>{{ row[1] }}</td>
</tr>
{% endfor %}


<!--
	일반적인 형식
    
	{% if문 or for문 %}
    
    {{ 변수나 표현식}}
    	...	....
    {% endif 또는 endfor %}
-->

Docs : jinja.palletsprojects.com/en/2.11.x/templates/

 

Template Designer Documentation — Jinja Documentation (2.11.x)

This document describes the syntax and semantics of the template engine and will be most useful as reference to those creating Jinja templates. As the template engine is very flexible, the configuration from the application can be slightly different from t

jinja.palletsprojects.com

 

📝 블루 프린트

Flask의 요청으로 URL을 생성 할 때 화면을 출력하는 함수를 블루 프린트와 연결한다.

블루 프린트는 웹 애플리케이션의 개체를 미리 요구하지 않고 기능을 정의할 수 있다.
또한, 파일을 여러개로 나누어 유지 보수 측면에서 매우 효과적으로 개발할 수 있게끔 할 수 있다.

블루 프린트 없이 flask 웹 애플리케이션을 만들 수 있다.
하지만 여러 기능이 포함된 웹 애플리케이션을 제작하고자 한다면 블루프린트를 사용하는 것을 권장한다.

from flask import Blueprint, render_template, abort
from jinja2 import TemplateNotFound

simple_page = Blueprint('simple_page', __name__,
                        template_folder='templates')

@simple_page.route('/', defaults={'page': 'index'})
@simple_page.route('/<page>')
def show(page):
    try:
        return render_template('pages/%s.html' % page)
    except TemplateNotFound:
        abort(404)

@simple_page.route 장식자를 이용해 함수를 바인딩하면 구현한 show() 함수를 통해 블루 프린트가 동작하게 된다.
만약 블루 프린트 등록하려면 아래와 같이 register_blueprint() 함수를 이용하면 된다.

from flask import Flask
from yourapplication.simple_page import simple_page

app = Flask(__name__)
app.register_blueprint(simple_page)

 

📝 예제 ) 간단한 게시판 ( CRUD )

from flask import Flask, render_template, request, redirect, url_for

app = Flask(__name__)
board = []

# 게시판 내용 조회 (Read)
@app.route('/')
def index():
    return render_template('list.html', rows=board)

# 게시판 내용 추가 (Create)
@app.route('/add',methods=["POST"])
def add():
    if request.method == "POST":
        name = request.form["name"]
        context = request.form["context"]
        board.append([name,context])
        return redirect(url_for("index"))
    else:
        return render_template("list.html", rows=board)

# 게시판 내용 갱신 (Update)
@app.route('/update/<int:uid>', methods=["GET","POST"])
def update(uid):
    if request.method == "POST":
        index = uid - 1
        name = request.form["name"]
        context = request.form["context"]
        
        board[index] = [name,context]   # 기존의 board내용에 덮어쓰기
        return redirect(url_for("index"))
    else:
        return render_template("update.html",index=uid,rows=board)

# 게시판 내용 삭제 (Delete)
@app.route('/delete/<int:uid>')
def delete(uid):
    index = uid - 1
    del board[index]

    return redirect(url_for("index"))


if __name__ == '__main__':
    app.run(debug=True)
<!-- ./template/list.html -->

<!doctype html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <meta name="Generator" content="EditPlus®">
    <meta name="Author" content="">
    <meta name="Keywords" content="">
    <meta name="Description" content="">
    <title>SQLite3 게시판 등록</title>

    <style type="text/css">
        body {
            text-align: center;
        }
    </style>
</head>

<body>
    <h3>게시판</h3>
    <h4>추가</h4>
    <form action="/add" method="POST">
        이름<br>
        <input type="text" name="name" /><br>
        내용<br>
        <input type="text" name="context" style="text-align:center; width:400px; height:100px;" /><br><br>
        <input type="submit" value="게 시" /><br>
    </form>
    <h4>목록보기</h4>
    <table border=1 width="600" align="center">
        <thead>
            <td>목차</td>
            <td>이름</td>
            <td>내용</td>
            <td>수정, 삭제</td>
        </thead>
        {% for row in rows %}
        <tr>
            <td>{{ loop.index }}</td>
            <td>{{ row[0] }}</td>
            <td>{{ row[1] }}</td>
            <td><a href="{{url_for('update', uid = loop.index)}}">수정</a> <a
                    href="{{url_for('delete', uid = loop.index)}}">삭제</a></td>
        </tr>
        {% endfor %}
    </table>
</body>

</html>
<!-- ./templates/update.html -->

<!doctype html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <meta name="Generator" content="EditPlus®">
    <meta name="Author" content="">
    <meta name="Keywords" content="">
    <meta name="Description" content="">
    <title>SQLite3 게시판 등록</title>

    <style type="text/css">
        body {
            text-align: center;
        }
    </style>
</head>

<body>
    <h3>게시판</h3>
    <h4>수정</h4>
    <form action="/update/{{index}}" method="POST">
        이름<br>
        <input type="text" name="name" /><br>
        내용<br>
        <input type="text" name="context" style="text-align:center; width:400px; height:100px;" /><br><br>
        <input type="submit" value="수 정" /><br>
    </form>
    <h4>기존</h4>
    <table border=1 width="600" align="center">
        <thead>
            <td>목차</td>
            <td>이름</td>
            <td>내용</td>
        </thead>
        <tr>
            <td>{{ index}}</td>
            <td>{{ rows[index-1][0] }}</td>
            <td>{{ rows[index-1][1] }}</td>
        </tr>
    </table>
</body>

</html>

[ 출처 : elice ]

 

728x90
반응형

📝 REST란 무엇인가 ?

REST : Representational State Transfer

= 자원을 이름(자원의 표현)으로 구분하여 해당 자원의 상태를 주고 받는 것을 의미한다.
= 즉, 자원(resourece) 의 표현(representation)에 의한 "상태 전달"

  • 자원의 표현
    • 자원 : 해당 소프트웨어가 관리하는 모든 것 ( ex. 그림, 문서, 데이터 등 )
    • 자원의 표현 : 그 자원을 표현하기 위한 이름
  • 상태(정보) 전달
    • 데이터가 요청되는 시점에서 자원의 상태(정보)를 전달한다.
    • JSON 혹은 XML을 통해 데이터를 주고 받는 것이 보통의 전달 방식이다.

WWW(World Wide Web) 와 같은 시스템을 위한 소프트웨어 개발 아키텍처의 한 형식이다.

REST는 기본적으로 웹의 기존 기술과 HTTP 프로토콜을 그대로 사용하기 때문에, 웹의 장점을 최대한 활용할 수 있는
아키텍처 스타일이다. REST는 네트워크 상에서 클라이언트와 서버 사이의 통신 방식 중 하나이다.

 

💡 REST의 구체적인 개념

HTTP URI(Uniform Resource Identifier)을 통해 자원을 명시하고, HTTP Method(POST, GET, PUT, DELETE)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것을 의미한다.

  • REST는 자원 기반의 구조(ROA) 설계의 중심에 자원이 있고, HTTP Method를 통해 자원을 처리하도록 설계된 아키텍쳐를 의미한다.

💡 CRUD

  • Create : 생성(POST)
  • Read : 조회(GET)
  • Update : 갱신(PUT)
  • Delete : 삭제(DELETE)
  • HEAD : header 정보 조회(HEAD)

💡 REST 장단점

장점

  • 서버와 클라이언트의 역할을 명확하게 분리한다.
  • 여러가지 서비스 디자인에서 생길 수 있는 문제를 최소화한다.
  • REST API 메시지가 의도하는 바를 명확하게 나타내므로, 의도하는 바를 쉽게 파악할 수 있다.
  • HTTP 표준 프로토콜에 따르는 모든 플랫폼에서 사용이 가능하다.
  • HTTP 표준 프로토콜의 표준을 최대한 활용하여 여러 추가적인 장점을 함께 가져갈 수 있게 해준다.

단점

  • 사용할 수 있는 메소드가 4가지 밖에 없다. (POST,GET,PUT,DELETE)
  • 표준이 존재하지 않는다.

💡 그럼에도, REST가 왜 필요한가 ?

  • 다향한 클라이언트의 등장
  • 애플리케이션 분리 및 통합

최근 서버 프로그램은 다양한 브라우저(chrome, Explorer, safari 등)와 안드로이드폰, 아이폰과 같은 모바일 디바이스에서도 통신할 수 있어야 하기 때문이다.

💡 REST 구성요소

  • 자원(Resource) : URI
    • 웹 서버의 자원은 각자 이름을 가지고 있다.
    • 따라서, 클라이언트는 이러한 이름을 통해 원하는 정보를 찾을 수 있다.
    • 이때 서버 자원의 이름을 URI라고 한다.
  • 행위(Verb) : HTTP Method
    • HTTP 프로토콜은 GET,POST,PUT,DELETE와 같은 메서드를 제공한다.
  • 표현(Representation of Resource)
    • 클라이언트가 자원의 상태(정보)에 대해 요청하면, 서버는 이에 적절한 응답을 보내야한다.
    • REST의 하나의 자원은 JSON, XML, TEXT, RSS 등 여러 형태의 응답으로 나타낼 수 있다.
    • 하지만, 보통 JSON 이나 XML을 통해 데이터를 주고 받는 것이 일반적이다.

 

📝 HTTP Method : [ POST ]

HTTP 메소드 중 POST는 요청을 처리하기 위해 사용자(클라이언트)로부터 특정 양식(form)의 "데이터를 암호화"하여 서버로 전송하는 방법이다.

서버는 POST 방식으로 전달 받은 데이터를 통해 특정 동작을 수행할 수 있다.
예로 로그인 예시를 보자.

<!-- login.html -->
<html>  
   <body>  
      <form action = "/login" method = "post">  
         <table>  
        <tr><td>아이디</td>  
        <td><input type ="text" name ="id"></td></tr>  
        <tr><td>비밀번호</td>  
        <td><input type ="password" name ="pass"></td></tr>  
        <tr><td><input type = "submit"></td></tr>  
    </table>  
      </form>  
   </body>  
</html>
# login.py

from flask import *  
# Flask 인스턴스 생성
app = Flask(__name__) 


@app.route('/')
def hello():
    return render_template('login.html')


# login 주소에서 POST 방식의 요청을 받았을 때
@app.route('/login',methods = ['POST'])  
def login():  
    id = request.form['id']  
    passwrd = request.form['pass'] 

    if id=="Elice" and passwrd=="Awesome!": 
        return "Welcome %s" % id  


if __name__ == '__main__':  
    app.run()

[ 출처 : elice ]

이는, login.html 에서 "아이디"와 "비밀번호"를 입력하고, "버튼을 누르면" login.py 에서 이를 인식해서
"Elice" 이고, 비밀번호가 "Awesome!" 이면, "Welcome Elice" 라는 문구가 나타난다.

 

📝 HTTP Method : [ GET ]

GET 요청 또한 사용자(클라이언트)로부터 특정 양식(form)의 데이터를 서버로 전송하는 방법이다.

가장 큰 차이는 정보를 URL에 붙여서 보내게 되고, 즉, "데이터가 암호화되지 않는다는 점"이다.

앞선 로그인 예시를 통해 보자.

<!-- login.html -->
<html>  
   <body>  
      <form action = "/login" method = "get">  
         <table>  
        <tr><td>아이디</td>  
        <td><input type ="text" name ="id"></td></tr>  
        <tr><td>비밀번호</td>  
        <td><input type ="password" name ="pass"></td></tr>  
        <tr><td><input type = "submit"></td></tr>  
    </table>  
      </form>  
   </body>  
</html>
# login.py

from flask import *  
# Flask 인스턴스 생성
app = Flask(__name__)  


# login 주소에서 GET 방식의 요청을 받았을 때
# @app.route()에서 methods 인자의 기본 값은 GET으로 생략해서 작성해도 됩니다.
@app.route('/login',methods = ['GET'])  
def login():  
      id = request.args.get['id']  
      passwrd = request.args.get['pass']  
      if id=="Elice" and passwrd=="Awesome!": 
          return "Welcome %s" % id  


if __name__ == '__main__':  
   app.run()

[ 출처 : elice ]

 

GET이 POST 방식과 가장 큰 차이점은 URL에 "https://localhost:8080/login?id=elice&pass=awesome" 으로 표현된다.

즉, 로그인 할 때, URL에 아이디와 비밀번호가 표기된다. ( = 데이터가 암호화가 되지 않는다. )
이는, 한편으로 정보보안을 유지할 수 없다는 것을 의미한다.

따라서, "로그인"과 같이 정보를 가려야할 때는 GET이 아닌 POST 방식을 사용하는 것이 맞다.

 

📝 HTTP - POST 예제

POST 요청은 눈에 파라미터가 보이는 GET요청과 달리 전달하려는 정보가 HTTP body에 포함되어 전달된다.

전달하려는 정보는 form data, json strings 등이 있다.

render_templates( ) 메소드 = Flask 에서 html 파일을 "랜더링" 하기 위해서 사용한다.
( 랜더링(Rendering) = 웹 브라우저 상의 화면을 표현하는 과정 )

POST로 전달받은 "값"은 request.form[ '변수명' ]을 사용하면 html의 form에서 해당 변수명에 만족 값을 사용가능

from flask import Flask
from flask import request
from flask import render_template

app = Flask(__name__)

@app.route('/')
def hello():
    return render_template('index.html')


@app.route("/post", methods=['POST'])
def post():
    #1번을 해보세요!
    value = request.form["input"]
    msg = "%s 님 환영합니다." % value
    return msg


if __name__ == '__main__':
    app.run()
<!-- 사용하는 html 파일들은, 반드시 templates 디렉터리 안에 있어야한다. !! -->
<!-- /templates/index.html -->


<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>HTML for python flask</title>
</head>

<body>
    <form action = "/post" method="post">
        <p>
            이름 : 
            <input type="text" name = "input">
        </p>
        <p>
            이름을 입력하고 제출버튼을 누르세요.<br>
            <input type = "submit" value = "제출" onclick = "alert('제출 완료!')" />
        </p>
    </form>
</body>
</html>

아이디 입력란에 아이디를 입력하고 제출하면, 제출완료 ! 와 동시에
post 방식으로, input에 "id님 환영합니다." 출력 

 

📝 HTTP - GET 예제

Flask 에서 GET 또는 POST로 전달받은 정보를 request 모듈을 사용하여 활용할 수 있다.

GET 방식의 경우 모든 파라미터를 URL로 보내 요청하는 방식이라고 했다.

request 모듈에는 GET 방식으로 URL의 인자를 'key = value' 형태로 전달했을 때, 다음 방식으로 활용한다.

  • 다음과 예시와 같은 주소를 입력했을 시, number의 값은 = 1 (https://주소.com/?key=1)
number = request.args.get('key`, 초기값)

초기값은 key 값으로 아무 값도 넘겨받지 못했을 때 활용되는 값이다. 이후에는 URL을 통해 '/?key=value' 형태로
key값을 전달받으면 해당 값을 사용한다.

여러개의 key와 값을 전달받으려면 다음 예시와 같이 '&' 기호를 입력하여 추가할 수 있다. 

  • key의 값은 1, value의 값은 2 (https://주소.com/?key=1&value=2)
from flask import Flask
from flask import request

app = Flask(__name__)

@app.route('/')     # Default는  HTTP methods = ['GET ']
def user_juso():
    temp1 = request.args.get("word1","Elice")   # GET 방식으로, request.args.get() 할때, 
    temp2 = request.args.get("word2","Hello")   # 주소에 값이 지정안되면 기본값은, 다음과 같음을 의미
    return temp1 + "<br>" + temp2

if __name__ == '__main__':
    app.run()

GET 방식 -> URL에 값을 전달할 경우
      GET -> URL 에 값이 전달되지 않을 경우        = default 값으로 대체

 

📝 HTTP - GET & POST 예제

GET과 POST를 동시에 사용해서 웹 페이지를 동작 시킬 수 있다.

method가 GET이면 이름을 입력받는 웹 페이지를 동작시키고, POST라면 입력 같은 값을 포함하는 문장을 출력한다.

<!-- templates/index2.html -->

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>HTML for python flask</title>
</head>

<body>
    <form action = "/" method="POST">
        <p>
            이름 :
            <input type="text" id = "input" name = "input">
        </p>
        <p>
            이름을 입력하고 제출버튼을 누르세요.
            <input type = "submit" value = "제출" onclick = "alert('제출 완료!')" />
        </p>
    </form>
</body>
from flask import Flask, render_template, request

app = Flask(__name__)

@app.route('/', methods=["GET","POST"]) # GET 또는 POST가 호출될 수 있다는 것
def post():
    if request.method == "POST":
        value = request.form["input"]   # index2.html가서 form태크를 보면 요소에 method = "POST" 일것이다.
        return f"{value}님 환영합니다."
    
    if request.method == "GET":
        return render_template("index2.html")

if __name__ == '__main__':
    app.run()

GET 
form 입력, 즉 POST로 데이터를 보내겠다.
POST

 

📝 API 와 End point가 무엇인가 ?

API프로그램들이 서로 상호작용하는 것을 도와주는 매체이다.

우리가 음식점에 갔을 때, 아래와 같이 행동한다. 점원은 손님에게 메뉴를 알려주고, 주방에 주문받은 요리를 요청한다.
그 다음 주방에서 완성된 요리를 손님에게 다시 전달한다.

  • 손님과 요리사는 "End Point"
  • 점원은 이 둘 사이에서 "API"

[ 출처 : elice ]

API는 손님(프로그램)이 주문할 수 있게 메뉴(명령 목록)를 정리하고, 주문(명령)을 받으면 요리사(응용프로그램)와 상호작용하여 요청된 메뉴(명령에 대한 값)를 전달한다.

 

💡 API의 역할은 무엇인가 ?

1. API는 서버와 데이터베이스에 대한 출입구 역할을 한다.

  • 데이터베이스에는 정보들이 저장된다. 
  • 따라서, 모든 사람들이 이 데이터베이스에 접근할 수 있으면 안된다.
  • API는 이를 방지하기 위해 우리가 가진 서버와 데이터베이스에 대한 출입구 역할을 하며, 허용된 사람들에게만 접근성을 부여해준다.

2. API는 프로그램과 기기가 원활하게 통신할 수 있도록 한다.

  • 우리가 흔히 알고 사용하고 있는 스마트폰 어플이나 프로그램과 기기가 데이터를 원활히 주고 받을 수 있도록 돕는 역할을 한다.

3. API는 모든 접속을 표준화한다.

  • API는 모든 접속을 표준화하기 때문에 기기나 운영체제 등과 상관없이 누구나 동일한 권한을 얻을 수 있다.

 

💡 API Testing

API Testing 은 API를 테스트하여 기능, 성능, 신뢰성, 보안 측면에서 기대를 충족하는지 확인하는 테스팅의 한 유형

완벽하게 작동하는 API만이 실제 애플리케이션에서 사용할 수 있다.
따라서, 정상적으로 완벽하게 작동하는지 테스트 해야한다.
API 테스트를 진행하게 되면 향후 특정 시점에서 발생할 수 있는 애플리케이션의 많은 문제점들을 해결할 수 있다.

[ 출처 : elice ]

728x90
반응형

+ Recent posts