일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- spring 환경설정
- java설치
- 노마드코더
- 플랙스박스기본
- ubuntu
- 자바 스프링
- Flex Box 기본
- java spring
- 자바스프링
- numpy
- SQL 문제
- 오산대맛집
- 관계형데이터베이스
- node.js
- 이클립스
- SQL 연산자
- Eclipse
- 스프링
- Hooks
- 타입
- 객체지향프로그래밍
- 환경설정
- 람다식
- spring
- REACT
- Flexbox Froggy
- SQL 명령어
- HTML5
- SQL
- 리액트
- Today
- Total
이것저것
(6) 회원가입 구현하기 본문
전체적인 파일 구성이다.
-참고자료-
나는 게시판은 안만들고 회원가입만 진행했기때문에
글 위쪽에 모델만드는 부분은 내가 작성한 모델 생성하기 글을 참고하면 될것같다
https://gomtaetae.tistory.com/entry/%EB%AA%A8%EB%8D%B8-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0
-폼 만들기 참고-
모델을 생성한 다음에 회원가입 폼을 작성해보자
먼저 플라스크의 폼 모듈을 사용하려면 설치를 진행해야한다.
pip install flask-wtf
Flask-WTF를 사용하려면 환경변수 SECRET_KEY가 필요하다고한다.
SECRET_KEY는 데이터 위변조를 방지하기위해서 사용한다고한다.
세션유지의 Token과는 다른 의미이다.
flask-wtf을 설치후 config.py에 SECRET_KEY를 추가해주자.
DMS/config.py
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:1234@localhost/dms'
SQLALCHEMY_TRACK_MODIFICATIONS = False
# 추가
SECRET_KEY = "dev"
SECRET_KEY='dev'는 매우 위험한 설정이라고한다.
하지만 지금은 개발환경이니까 괜찮다고한다. 나중에 SECRET_KEY 설정하는 방법을 알려주면 수정해야겠다.
flask-wtf을 설치하고 SECRET_KEY까지 설정 완료했다면
이제 회원가입 정보를 받을 form을 작성해보자
pybo/forms.py 에 작성했다.
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, EmailField
from wtforms.validators import DataRequired, Length, EqualTo, Email
# 회원가입 폼
class UserCreateForm(FlaskForm):
nickname = StringField(
'아이디',
validators=[DataRequired(), Length(min=3, max=25)]
)
users_name = StringField(
'사용자 이름',
validators=[DataRequired(), Length(min=3, max=25)]
)
password1 = PasswordField(
'비밀번호',
validators=[
DataRequired(), EqualTo('password2', '비밀번호가 일치하지 않습니다.')]
)
password2 = PasswordField(
'비밀번호확인',
validators=[DataRequired()]
)
email = EmailField(
'이메일',
validators=[DataRequired(), Email()]
)
users_birth = StringField(
'생년월일',
validators=[DataRequired(), Length(min=8, max=8, message='생년월일은 8자리여야 합니다. ex)19961020')]
)
users_phone = StringField(
'전화번호',
validators=[DataRequired(), Length(min=10, max=15)] # 전화번호 형식에 맞춰 길이를 조정하세요.
)
address_main = StringField(
'주소',
validators=[DataRequired()]
)
address_sub = StringField(
'상세주소',
validators=[DataRequired()]
)
여기서 email부분에 Email()은 abc@abc.com과 같은 이메일 형식이 맞는지 아닌지 확인하는 함수이다.
생년월일은 예를 들어 231125처럼 6자리로 하고 싶었는데 Date로 받았더니 형식이 YYYY.MM.DD 여서 어쩔수 없이 8자리로 했다. 6자리로 줄이는건 나중에 다시 찾아볼 예정
pip install email_validator
email_validator를 깔아야지 돌아가므로 설치해준다.
회원가입 폼데이터 처리
데이터를 처리해주기 위해 auth_views.py파일을 만들어준다.
from flask import Blueprint, url_for, render_template, request
from werkzeug.security import generate_password_hash
from werkzeug.utils import redirect
from pybo import db
from pybo.forms import UserCreateForm
from pybo.models import Users
bp = Blueprint('auth', __name__, url_prefix='/auth')
# 회원가입 폼 입력받기
@bp.route('/signup', methods=('GET', 'POST'))
def signup():
form = UserCreateForm()
if request.method == 'POST' and form.validate_on_submit():
user_by_email = Users.query.filter_by(email=form.email.data).first()
user_by_nickname = Users.query.filter_by(nickname=form.nickname.data).first()
if user_by_email:
flash('이미 사용 중인 이메일입니다.')
elif user_by_nickname:
flash('이미 사용 중인 닉네임입니다.')
else:
users = Users(
nickname=form.nickname.data,
users_name=form.users_name.data,
password=generate_password_hash(form.password1.data),
email=form.email.data,
users_birth=form.users_birth.data,
users_phone=form.users_phone.data,
address_main=form.address_main.data,
address_sub=form.address_sub.data
)
db.session.add(users)
db.session.commit()
return redirect(url_for('main.index'))
return render_template('auth/signup.html', form=form)
werkzeug은 Flask를 설치할때 같이 설치되는 것이라고한다.
generate_password_hash는 보통 비밀번호를 안전하게 저장하기위해서 hash라는 것을 사용하는데 이를 사용할 수 있도록 해주는 것이다.
blueprint를 사용해서 /auth라는 url을 가진 라우트를 그룹하하는데 사용했다.
@bp.route로 /auth/signup 이라는 url을 생성, 해당 라우트에서 GET, POST 메소드를 처리할 수 있게한다.
위에서 만든 UserCreateForm 폼을 사용한다.
먼저 POST로 이메일과 닉네임을 비교해서 이미 사용중인지 확인한다.
그리고 둘다 겹치지 않을 시 회원가입이 진행되도록 한다.
이제 새로 만든 blueprint를 __init__.py에 추가해준다.
from flask import Flask
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
import config
db = SQLAlchemy()
migrate = Migrate()
# create_app함수가 app 객체를 생성해 반환하도록 하는 이유는
# app=Flask(__name__)을 전역으로 사용하게되면 오류가 발생하기 때문(순환 참조 오류)
# create_app이 '애플리케이션 팩토리'이다.
# create_app 대신 다른 이름을 사용하면 정상작동하지 않는다.
def create_app():
app = Flask(__name__)
app.config.from_object(config)
# ORM
db.init_app(app)
migrate.init_app(app, db)
from . import models
# 블루프린트 작업 : Flask에서 URL과 함수의 매핑을 관리하기 위해 사용하는 도구이다.
# 블루프린트를 이용하면 라우팅 함수를 체계적으로 관리할 수 있다.
from .views import main_views, auth_views
app.register_blueprint(main_views.bp)
app.register_blueprint(auth_views.bp)
return app
blueprint 를 추가해 줄때는 from 부분에 추가한 파일 이름을 먼저 적어주고
app.register_blueprint로 생성한 bp를 추가해준다.
회원가입 템플릿 생성
이제 페이지에서 회원가입 정보를 입력 받을 페이지를 만들어보자
template에 auth라는 폴더를 만들고 signup.html 파일을 생성한다.
{% extends "base.html" %}
{% block content %}
<div class="container">
<h5 class="my-3 border-bottom pb-2">계정생성</h5>
<form method="post">
{{ form.csrf_token }}
{% include "form_errors.html" %}
<div class="mb-3">
<label for="nickname">사용자 아이디</label>
<input type="text" class="form-control" name="nickname" id="nickname"
value="{{ form.nickname.data or '' }}">
</div>
<div class="mb-3">
<label for="users_name">사용자 이름</label>
<input type="text" class="form-control" name="users_name" id="users_name"
value="{{ form.users_name.data or '' }}">
</div>
<div class="mb-3">
<label for="password1">비밀번호</label>
<input type="password" class="form-control" name="password1" id="password1"
value="{{ form.password1.data or '' }}">
</div>
<div class="mb-3">
<label for="password2">비밀번호 확인</label>
<input type="password" class="form-control" name="password2" id="password2"
value="{{ form.password2.data or '' }}">
</div>
<div class="mb-3">
<label for="email">이메일</label>
<input type="text" class="form-control" name="email" id="email"
value="{{ form.email.data or '' }}">
</div>
<div class="mb-3">
<label for="users_birth">생년월일</label>
<input type="text" class="form-control" name="users_birth" id="users_birth"
value="{{ form.users_birth.data or '' }}">
</div>
<div class="mb-3">
<label for="users_phone">핸드폰 번호</label>
<input type="text" class="form-control" name="users_phone" id="users_phone"
value="{{ form.users_phone.data or '' }}">
</div>
<div class="mb-3">
<label for="address_main">주소</label>
<input type="text" class="form-control" name="address_main" id="address_main"
value="{{ form.address_main.data or '' }}">
</div>
<div class="mb-3">
<label for="address_sub">상세 주소</label>
<input type="text" class="form-control" name="address_sub" id="address_sub"
value="{{ form.address_sub.data or '' }}">
</div>
<button type="submit" class="btn btn-primary">생성하기</button>
</form>
</div>
{% endblock %}
base.html을 사용해서 위아래 다 짜르고 form 부분만 만들면된다.
{{ form.csrf_token }}
{% include "form_errors.html" %}
이부분은 닉네임, 이메일 중복, 비밀번호 확인이 맞지 않을때 발생하는 오류를 띄워주기 위해 삽입했다.
즉, form_errors.html을 만들어야한다는 이야기다
templates 폴더 안에 생성하였다.
<!-- 필드오류 -->
{% if form.errors %}
<div class="alert alert-danger" role="alert">
{% for field, errors in form.errors.items() %}
<strong>{{ form[field].label }}</strong>
<ul>
{% for error in errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endfor %}
</div>
{% endif %}
<!-- flash 오류 -->
{% for message in get_flashed_messages() %}
<div class="alert alert-danger" role="alert">
{{ message }}
</div>
{% endfor %}
if form.errors로 유효성 검사 오류가 있는지 확인한다.
field, errors in form.errors.item으로 각 필드와 해당 필드의 오류 목록을 반환한다.
form[field].label은 오류가 발생한 필드의 라벨을 표시
ul 안쪽에서 해당 필드에 대한 오류 메세지를 li태그로 감싸서 표시한다.
flash 오류는 서버측에서 발생한 특정 이벤트나 액션에 대해 사용자에게 피드백을 제공한다.
이제 마무리단계이다....
navbar에 계정생성 부분에 signup으로 갈 수 있게 링크를 걸어주면된다.
<!-- 네비게이션바 -->
<nav class="navbar navbar-expand-lg navbar-light bg-light border-bottom">
<div class="container-fluid">
<a class="navbar-brand" href="{{ url_for('main.index') }}">Pybo</a>
<button class="navbar-toggler" type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent"
aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link" href="{{ url_for('auth.signup') }}">계정생성</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">로그인</a>
</li>
</ul>
</div>
</div>
</nav>
이제 회원가입 페이지에 가서 입력을해보면 전부 확인해 볼수 있다.
회원가입이 제대로되면 메인화면으로 돌아갈것이다.
그리고 MySQL에서
select * from dms.users
명령어를 사용해서 제대로 들어왔는지 확인도 가능하다
그럼 다음에 로그인 로그아웃으로 마무리하겠다.
'Python' 카테고리의 다른 글
(7) 로그인 로그아웃 구현 (0) | 2023.11.29 |
---|---|
(5) Flask Jinja2를 사용해 표준 HTML과 템플릿 상속 사용하기 (0) | 2023.11.25 |
(4) 메인 페이지 및 bootstrap, navbar 설정 (0) | 2023.11.25 |
(3) 모델 생성하기 (5) | 2023.11.23 |
(2) pycharm에 mysql 불러오기 (2) | 2023.11.22 |