>
회원 가입 기능은 쉽다.
아래 포스팅에서 설명한 것 처럼 회원정보를 DB에 저장하기만 하면 된다.
https://marketerbong.tistory.com/52
mongoDB 사용하는 방법(데이터 저장, 찾기, 변경하기, 지우기 등)
자, 이제 준비는 다 되었다. 이제 python 패키지를 설치만 하면 진짜 준비가 끝나간다.pymongodnspython위 2개의 패키지를 설치하자. 아래와 같이 작성하면 db에 접속이 가능하다.[pymongo 기본 코드]from p
marketerbong.tistory.com
다만 핵심은 암호화, 복호화에 있다.
우선 비밀번호를 사이트 관리자가 알게 된다면 개인정보 유출의 우려가 크다.
그렇기 때문에, 비밀번호를 암호화해서 저장하고, 로그인 시에는 암호를 푸는 복호화 작업이 필요하다.
내가 평소와 같이 영문+숫자 조합으로 10~16자 정도만 넣어도, 아래와 같이 길고 복잡하게 암호화 되어 저장된다.
다시 로그인 할 때는 회원가입할 때 쓴 비밀번호 10~16자 정도만 넣어도 자동으로 복호화되어 로그인되며, 비밀번호 변경 시 다시 암호화 되는 과정을 거친다.
간단히 기능 구현이 목표이기에 아래와 같이 닉네임, 이메일(id), 비밀번호(pw)를 입력하고, [회원가입] 버튼을 누르면 회원가입이 되도록 구현했다. 로그인 하기 기능은 다음 포스팅에서 다룰 예정이다.
파이썬에서는 다음과 같이 데이터를 처리해줬다.
※ 블루프린트를 사용해 구조화했기 때문에 라우터가 app.route가 아닌, bp.route이다.
from flask import Flask, render_template, request, jsonify, Blueprint
from pymongo import MongoClient
import certifi
import hashlib
bp = Blueprint("join", __name__, template_folder="templates")
ca = certifi.where()
client = MongoClient("mongodb+srv://몽고디비아이디:패스워드@cluster0.hecgbmx.mongodb.net/Cluster0?retryWrites=true&w=majority", tlsCAFile = ca)
db = client.bongdroid
# 이건 노출되면 안됨. 그러니 자주 안쓰고 알 수 없는 것으로 하자.
SECRET_KEY = 'password'
@bp.route('/')
def joinCall():
return render_template('join.html')
# 회원가입
@bp.route('/', methods=['POST'])
def api_register():
email_receive = request.form['email_give']
password_receive = request.form['password_give']
name_receive = request.form['name_give']
password_hash = hashlib.sha256(password_receive.encode('utf-8')).hexdigest()
# 이미 존재하는 아이디면 패스!
result = db.user.find_one({'email': email_receive})
if result is not None:
return jsonify({'result': 'fail', 'msg': '이미 존재하는 ID(이메일)입니다.'})
else:
db.user.insert_one({'email': email_receive, 'password': password_hash, 'name': name_receive})
return jsonify({'result': 'success'})
여기서 핵심은 암호화이다. 나는 hashlib 모듈을 사용했다. sha256 알고리즘으로 문자열을 해싱하도록 도와주는 모듈이다.
아래 한 줄로 패스워드를 받아서 암호화 하는 것이다. 그리고 저장할 때 [password_hash]로 저장하는 것이다.
password_hash = hashlib.sha256(password_receive.encode('utf-8')).hexdigest()
그리고 html 파일은 다음과 같다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
<link rel="stylesheet" href="/static/css/join.css" >
<link rel="stylesheet" href="/static/css/font.css">
<script>
const joinCall = () => {
if ($('#email').val() == ""){
alert('아이디(이메일 주소)를 입력해주세요.')
return false;
}
if ($('#password').val() == ""){
alert('비밀번호를 입력해주세요.')
return false;
}
if ($('#name').val() == ""){
alert('이름을 입력해주세요.')
return false;
}
$.ajax({
type: "POST",
url: "/join",
data: {
email_give: $('#email').val(),
password_give: $('#password').val(),
name_give: $('#name').val()
},
success: function (response) {
if (response['result'] == 'success') {
alert('회원가입이 완료되었습니다.')
window.location.href = '/join_finish'
} else {
alert(response['msg'])
}
}
})
}
</script>
<title>회원가입</title>
</head>
<body>
<div>
<div class="wrap">
<div class="login">
<h2>회원정보를 입력하세요</h2>
<div class="login_id">
<h4>닉네임</h4>
<input type="text" id="name" placeholder="Nickname" required>
</div>
<div class="login_id">
<h4>이메일</h4>
<input type="email" name="email" id="email" placeholder="Email" minlength="5" required>
<div id="error_mail" class="result-email result-check"></div>
</div>
<div class="login_pw">
<h4>비밀번호</h4>
<input type="password" name="" id="password" placeholder="Password" required>
</div>
<div class="submit">
<input class="mb-3" type="submit" onclick="joinCall()" value="회원가입">
<p class="submit_text">이미 회원이라면??</p>
<input type="submit" onclick="location.href='/login'" value="로그인하러가기">
</div>
</div>
</div>
</div>
<!-- 이메일 검증 -->
<script>
function email_check( email ) {
var regex=/([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
return (email != '' && email != 'undefined' && regex.test(email));
}
$("input[type=email]").blur(function(){
var email = $(this).val();
if( email == '' || email == 'undefined') return;
if(! email_check(email) ) {
$(".result-email").text('이메일 형식으로 적어주세요');
$(this).focus();
return false;
}else {
$(".result-email").text('');
}
});
</script>
</body>
</html>
css 파일은 알아서 꾸미고, 여기서 핵심은 이메일 유효성 검사 이다. 이메일 형식이 아닌데 회원가입이 될 수도 있기 때문에, 유효성 검사를 통해 이메일 형식이 아닌 경우는 이메일 형식으로 적어달라는 안내를 하는 것이다.
비밀번호 변경 기능을 만들어보자! (ft. JWT 암호화/복호화) (0) | 2024.10.28 |
---|---|
회원 로그인 기능을 만들어보자! (쿠키값 생성 및 유지 - ft. JWT 토큰) (0) | 2024.10.28 |
햄버거 메뉴를 만들자!(반응형) (0) | 2024.10.27 |
블루프린트로 파이썬 파일을 관리중인데, html 파일이 안불러와진다면? (0) | 2024.10.26 |
header와 footer 영역을 전체 공통으로 분리하여 사용하기(aka. 공통으로 노출되는 영역 만들기) (0) | 2024.10.26 |