22.11.13 ~ 22.11.19 배운 목록.
1. 회원가입, 로그인 기능 구현
2. JWT
3. 카카오 맵 api 활용
4. 알고리즘을 풀며 느낀 점
1. 회원가입, 로그인 기능 구현
- DB에 비밀번호를 저장할 때 해시 함수를 사용하여 누군가가 db에 접근해도 비밀번호를 못 알아내게 저장한다.
- 입력받은 아이디 값과 해시 함수를 적용한 비밀번호를 DB에 비교하여 찾아내는 방법으로 로그인한다.
[프로젝트 때 작성한 코드]
@app.route('/api/login', methods=['POST'])
def api_login():
id_receive = request.form['id_give']
pw_receive = request.form['pw_give']
# 회원가입 때와 같은 방법으로 pw를 암호화합니다.
pw_hash = hashlib.sha256(pw_receive.encode('utf-8')).hexdigest()
# id, 암호화된pw을 가지고 해당 유저를 찾습니다.
result = db.user.find_one({'id': id_receive, 'pw': pw_hash})
nickname_receive = result['nick']
# 찾으면 JWT 토큰을 만들어 발급합니다.
if result is not None:
# JWT 토큰에는, payload와 시크릿키가 필요합니다.
# 시크릿키가 있어야 토큰을 디코딩(=풀기) 해서 payload 값을 볼 수 있습니다.
# 아래에선 id와 exp를 담았습니다. 즉, JWT 토큰을 풀면 유저ID 값을 알 수 있습니다.
# exp에는 만료시간을 넣어줍니다. 만료시간이 지나면, 시크릿키로 토큰을 풀 때 만료되었다고 에러가 납니다.
payload = {
'id': id_receive,
'nickname': nickname_receive,
'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1)
}
token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
# token을 줍니다.
return jsonify({'result': 'success', 'token': token})
# 찾지 못하면
else:
return jsonify({'result': 'fail', 'msg': '아이디/비밀번호가 일치하지 않습니다.'})
2. JWT
- JWT 토큰을 만들 때 필요한 비밀 문자열인 SECURITY_KEY가 필요하다.
- SECURITY_KEY는 백엔드(서버)만 알고 있기 때문에, 서버에서만 토큰을 인코딩 및 디코딩을 할 수 있다.
- JWT(JSON Web Token): 특별한 인증 토큰
모바일이나 웹의 사용자 인증을 위해 사용하는 암호와 된 토큰을 말한다.
JWT 정보를 request에 담아 사용자용 정보 열람, 수정 등 개인적인 작업 들을 수행할 수 있게 한다.
- 토큰(Token):
사용자에 대한 정보를 암호화해서 브라우저에 저장하고, 웹페이지 접속 시, 저장된 정보를 가져와
사용자마다 다른 화면을 보여주는 용도로 사용할 수 있다.
- 인코딩과 디코딩:
인코딩(Encoding)이란 사람이 인지할 수 있는 문자(언어)를 약속된 규칙에 따라 컴퓨터가 이해하는 언어로 이루어진 코드로 바꾸는 것을 통틀어 일컫는다. 즉, 인코딩 encoding이란 정해진 규칙에 따라 코드화 , 암호화, 부호화하는 것을 말한다.
디코딩(Decoding)은 인코딩의 반대되는 개념으로 복호화, 역 코드화의 의미를 가지고 있다.
3. 카카오 맵 api 활용
- 카카오 api를 사용하려면 카카오 디벨로퍼 사이트에서 api_key 값을 받아와야 한다.
- 카카오 맵 api 사용법은 여기에 가면 web, ios, android에서 많은 기능이나 샘플 코드를 볼 수 있다.
[프로젝트 때 작성한 코드]
<script type="text/javascript"
src="//dapi.kakao.com/v2/maps/sdk.js?appkey=비밀^^"></script>
<div id="map" class="map_veiw" style="width:50%;height:400px;"></div>
<script>
var infowindow = new kakao.maps.InfoWindow({zIndex: 1});
var mapContainer = document.getElementById('map'), // 지도를 표시할 div
mapOption = {
center: new kakao.maps.LatLng(37.566826, 126.9786567), // 지도의 중심좌표
level: 3 // 지도의 확대 레벨
};
// 지도를 생성합니다
var map = new kakao.maps.Map(mapContainer, mapOption);
// 장소 검색 객체를 생성합니다
var ps = new kakao.maps.services.Places();
// 키워드로 장소를 검색합니다
function search() {
let sellect0 = $('#region').text();
let sellect1 = $('#region-in').text();
ps.keywordSearch(`${sellect0} ${sellect1} 명랑핫도그`, placesSearchCB);
}
// 키워드 검색 완료 시 호출되는 콜백함수 입니다
function placesSearchCB(data, status, pagination) {
if (status === kakao.maps.services.Status.OK) {
// 검색된 장소 위치를 기준으로 지도 범위를 재설정하기위해
// LatLngBounds 객체에 좌표를 추가합니다
var bounds = new kakao.maps.LatLngBounds();
for (var i = 0; i < data.length; i++) {
displayMarker(data[i]);
bounds.extend(new kakao.maps.LatLng(data[i].y, data[i].x));
}
// 검색된 장소 위치를 기준으로 지도 범위를 재설정합니다
map.setBounds(bounds);
}
}
// 지도에 마커를 표시하는 함수입니다
function displayMarker(place) {
// 마커를 생성하고 지도에 표시합니다
var marker = new kakao.maps.Marker({
map: map,
position: new kakao.maps.LatLng(place.y, place.x)
});
// 마커에 클릭이벤트를 등록합니다
kakao.maps.event.addListener(marker, 'click', function () {
// 마커를 클릭하면 장소명이 인포윈도우에 표출됩니다
infowindow.setContent('<div style="padding:5px;font-size:12px;">' + place.place_name + '</div>');
infowindow.open(map, marker);
});
}
</script>
4. 알고리즘 풀며 느낀 점
- 알고리즘에서 외부 라이브러리를 import 해서 푼 문제가 많다. 사용한 함수들을 정리하자.
- 알고리즘이 많이 약한 것 같다. 부족한 부분을 알았으니 더 많이 알고리즘을 풀어야겠다.