일을 하다보니 카카오 OAuth 연동 로그인이 사파리 브라우저에서 안되는 이슈가 발생했다. 

 

이유는 간단했다. 

 

iCloud 비공개 릴레이가 켜져있는 경우 

 

사파리 브라우저를 사용하면 IP추적을 막기 위해 IP를 주기적으로 변경시키는데 이 경우 

 

카카오 정책상 로그인 도중에 IP 변경 되는 경우 계정 탈취 시도와 구분할 수 없기 때문에

 

로그인 실패로 처리한다는 것

 

iOS 17이 되면서 이 기능이 더 자주 켜지게 되고 있는 것 같다. 

 

 

사파리 브라우저에서 카카오 로그인이 안되면

 

설정 > 사용자 이름 > iCloud > 비공개 릴레이 이동 후 

사용하지 않도록 셋팅해보자 ~ 

import random
from PIL import Image, ImageDraw, ImageFont


# 수식 생성 함수
def generate_equation():
operand_count = random.randint(2, 3) # 항의 개수 (2-3)
equation = ""

# 랜덤하게 숫자와 연산자를 조합하여 수식 생성
for i in range(operand_count):
if i > 0:
operator = random.choice(["+", "-"]) # 연산자 선택 (+, -)
equation += operator
equation += str(random.randint(1, 9)) # 숫자 선택

# 곱하기 연산자 추가 (최대 1)
if random.random() < 0.5: # 50%의 확률로 곱하기 연산자 추가
equation += "X" + str(random.randint(1, 9))

# 나누기 연산자 추가 (최대 1)
if random.random() < 0.5: # 50%의 확률로 나누기 연산자 추가
divisor = random.randint(1, 9)
dividend = random.randint(1, 9) * divisor
equation += "/" + str(divisor)
answer = dividend / divisor

# 정답이 소수점으로 나오는 경우 다시 수식 생성
if answer != int(answer):
return generate_equation()

else:
# 정답 계산하여 수식 완성
answer = eval(equation.replace("X", "*"))

equation += " = "

return equation, int(answer)


# 이미지 크기 설정
image_width = 600
image_height = 100

# 이미지 저장 디렉토리
save_directory = "C:/app/math/"

# 폰트 설정
font_path = "C:/Windows/Fonts/Arial.ttf"
font_size = 40
font = ImageFont.truetype(font_path, font_size)

# 500개의 수식 이미지 생성 및 저장
for i in range(500):
equation, answer = generate_equation()

# 이미지 생성
image = Image.new("RGB", (image_width, image_height), (255, 255, 255))
draw = ImageDraw.Draw(image)

# 수식을 이미지에 그리기
draw.text((10, 10), equation, font=font, fill=(0, 0, 0))

# 이미지 저장
filename = save_directory + str(answer) + ".png"
image.save(filename)

 

* 코드 설명
수식을 저장한다.

항은 2-3개정도로 하고 조정이 가능하다.

최종적으로 파이썬py파일을 실행하면

수식이미지 500개가 나오고 정답은 파일명이다. (정답이 중복되면 덮어쓰니 주의)

 

위 코드로 만든 사칙연산 퀴즈는 아래 사이트에서 진행할 수 있다.

https://supercup.co.kr/quizstat?type=keNKrpTRZPgq&start=Y 

 

import os
import re
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin

# 저장할 디렉토리 경로
directory = "C:/app/pokemon9"

# 디렉토리가 존재하지 않을 경우 생성합니다.
if not os.path.exists(directory):
os.makedirs(directory)

# 포켓몬 번역 데이터를 포함한 딕셔너리 생성
translation_data = {
"Sprigatito": "나오하",
"Floragato": "나로테",
"Meowscarada": "마스카나",
"Fuecoco": "뜨아거",
"Crocalor": "악뜨거",
"Skeledirge": "라우드본",
"Quaxly": "꾸왁스",
"Quaxwell": "아꾸왁",
"Quaquaval": "웨이니발",
"Lechonk": "맛보돈",
"Oinkologne": "퍼퓨돈",
"Tarountula": "타랜툴라",
"Spidops": "트래피더",
"Nymble": "콩알뚜기",
"Lokix": "엑스레그",
"Pawmi": "빠모",
"Pawmo": "빠모트",
"Pawmot": "빠르모트",
"Tandemaus": "두리쥐",
"Maushold": "파밀리쥐",
"Fidough": "쫀도기",
"Dachsbun": "바우첼",
"Smoliv": "미니브",
"Dolliv": "올리뇨",
"Arboliva": "올리르바",
"Squawkabilly": "시비꼬",
"Nacli": "베베솔트",
"Naclstack": "스태솔트",
"Garganacl": "콜로솔트",
"Charcadet": "카르본",
"Armarouge": "카디나르마",
"Ceruledge": "파라블레이즈",
"Tadbulb": "빈나두",
"Bellibolt": "찌리배리",
"Wattrel": "찌리비",
"Kilowattrel": "찌리비크",
"Maschiff": "오라티프",
"Mabosstiff": "마피티프",
"Shroodle": "땃쭈르",
"Grafaiai": "태깅구르",
"Bramblin": "그푸리",
"Brambleghast": "공푸리",
"Toedscool": "들눈해",
"Toedscruel": "육파리",
"Klawf": "절벼게",
"Capsakid": "캡싸이",
"Scovillain": "스코빌런",
"Rellor": "구르데",
"Rabsca": "베라카스",
"Flittle": "하느라기",
"Espathra": "클레스퍼트라",
"Tinkatink": "어리짱",
"Tinkatuff": "벼리짱",
"Tinkaton": "두드리짱",
"Wiglett": "바다그다",
"Wugtrio": "바닥트리오",
"Bombirdier": "떨구새",
"Finizen": "맨돌핀",
"Palafin": "돌핀맨",
"Varoom": "부르롱",
"Revavroom": "우락고래",
"Cyclizar": "가비루사",
"Orthworm": "어써러셔",
"Glimmet": "싸리용",
"Glimmora": "초롱순",
"Greavard": "키키링",
"Houndstone": "노고고치",
"Flamigo": "불꽃새",
"Cetoddle": "물뚜껑",
"Cetitan": "물거인",
"Veluza": "바다소라",
"Dondozo": "물마리",
"Tatsugiri": "땅가리기",
"Annihilape": "저승갓숭",
"Clodsire": "토산염",
"Farigiraf": "장착노래",
"Dudunsparce": "두던스파",
"Kingambit": "킹엠비트",
"Great Tusk": "위대한엄니",
"Scream Tail": "우렁찬꼬리",
"Brute Bonnet": "사나운버섯",
"Flutter Mane": "날개치는머리",
"Slither Wing": "땅위를 기는날개",
"Sandy Shocks": "모래전격",
"Iron Treads": "무쇠바퀴",
"Iron Bundle": "무쇠보따리",
"Iron Hands": "무쇠손",
"Iron Jugulis": "무쇠목걸이",
"Iron Moth": "무쇠나방",
"Iron Thorns": "무쇠가시",
"Frigibax": "서리고드",
"Arctibax": "북극고드",
"Baxcalibur": "고드호른",
"Gimmighoul": "모으령",
"Gholdengo": "고스트레고",
"Wo-Chien": "파이찬",
"Chien-Pao": "얼어바",
"Ting-Lu": "춤추네",
"Chi-Yu": "기랑",
"Roaring Moon": "울부짖는 달",
"Iron Valiant": "무쇠용갑",
"Koraidon": "코라이돈",
"Miraidon": "미라이돈",
"Walking Wake": "걷는 파도",
"Iron Leaves": "무쇠잎새"
}


# 웹 페이지에 GET 요청을 보내고 응답을 받아옵니다.
url = "https://bulbapedia.bulbagarden.net/wiki/List_of_Pok%C3%A9mon_by_National_Pok%C3%A9dex_number"
response = requests.get(url)

# 응답의 텍스트를 BeautifulSoup 객체로 변환합니다.
soup = BeautifulSoup(response.text, 'html.parser')

# 테이블을 찾습니다.
tables = soup.find_all('table', class_='roundy')

# 3세대 포켓몬 데이터 추출
table_3rd_gen = tables[8]
for row in table_3rd_gen.find_all('tr', style=lambda style: style and 'background:#FFF' in style):
cells = row.find_all('td')
if len(cells) >= 4:
number = cells[0].text.strip()
english_name = cells[2].find('a').text.strip()
image_cell = cells[1]
image_url = image_cell.find('img')['src'] if image_cell.find('img') else None

if image_url and number:
# 이미지 URL에 스키마를 추가합니다.
image_url = urljoin(url, image_url)
# 이미지 URL에서 "70px" 부분을 "500px"로 변경합니다.
image_url = image_url.replace("70px", "500px")

# 번호 포맷 변경: #0252 -> (No.252)
number = re.sub(r'#0*(\d+)', r'(No.\1)', number)

# 포켓몬 이름을 한글로 번역
korean_name = translation_data.get(english_name, english_name)

# 파일명 포맷 변경: Treecko (No.252).png -> 나무지기 (No.252).png
file_name = f"{korean_name} {number}.png"
file_path = os.path.join(directory, file_name)

# 이미지 다운로드
response = requests.get(image_url)

# 이미지 저장
with open(file_path, 'wb') as f:
f.write(response.content)

print(f"번호: {number}")
print(f"영어 이름: {english_name}")
print(f"한글 이름: {korean_name}")
print(f"이미지 다운로드 완료: {file_path}")
print("---------------")

포켓몬스터 데이터를 저장하였다. 

파일명 포맷 변경하였고, 

 

포켓몬 이름을 한글로 변환하였다. 

위는 9세대 포켓몬을 크롤링하여 저장하는 로직이다.

 

번역데이터는 노가다가 아니라 chatgpt를 이용하여 억지로 만들었다.

 

chatgpt사용이 날이 갈수록 고도화되는 중이랄까..

 

chatgpt는 2021년 9월까지 학습해서 8세대 9세대 포켓몬의 이름은 몰랐다..

 

나무위키 정보랑 해당 url 정보를 조합해서 대화로 어떻게든 데이터를 번역시켰다.

 

귀여운 9세대 포켓몬

 

 

1세대부터 8세대까지 포켓몬도 

 

table_3rd_gen = tables[8]

이 값을 수정하면 출력할 수 있다.

1세대는 tables[0]이다.

 

영어랑 한글 번역은 chatgpt한테 문의하면 나온다..

 

 

그렇게 탄생한 ! 

이상형 월드컵 주소는 아래와 같다..

 

https://supercup.co.kr/matchstat?type=eCCb8BlKtPO2 

 

아이돌 움짤, 여자 IDOL 이상형 월드컵, 이상형 월드컵 게임, 이상형 월드컵 통계 SUPERCUP, 이상형만

공식적인 이상형 월드컵 사이트 - SUPERCUP입니다. 이상형 월드컵을 만들어서 즐겨보세요

supercup.co.kr

 

SuperCup에 인물퀴즈 기능을 오픈했습니다 ! 축하축하 ! 

 

인물퀴즈는 현재 여자아이돌, 여자배우, 남자아이돌, 남자배우, 랜덤 

총 5개의 인물퀴즈를 제공하고 있습니다.

 

본인의 덕후력을 테스트해보세요 !

 

https://www.supercup.co.kr/quizstat?type=random&start=Y 

 

아이돌 움짤, 여자 IDOL 이상형 월드컵, 이상형 월드컵 게임, 이상형 월드컵 통계 SUPERCUP, 이상형만

공식적인 이상형 월드컵 사이트 - SUPERCUP입니다. 이상형 월드컵을 만들어서 즐겨보세요

supercup.co.kr

 

 

  • Spring Boot & DDD(Domain-Driven Design) 아키텍처

 

DDD는 복잡한 도메인을 이해하고 구성하는 데에 초점을 맞춘 소프트웨어 개발 방법론입니다. 

 

이는 애플리케이션을 여러 개의 레이어로 나누어 도메인 모델을 중심으로 설계하는 것을 강조합니다. 

 

이러한 레이어는 각각의 책임과 역할을 가지며, 각각의 레이어는 독립적으로 변경될 수 있습니다.

 

Spring Boot는 Spring Framework의 간소화된 버전으로, Java 애플리케이션을 쉽게 구축할 수 있도록 도와줍니다. 

 

Spring Boot는 설정의 자동화, 내장된 서버, 스프링 기반 애플리케이션의 개발과 배포를 간편하게 만들어줍니다.

 

Spring Boot와 DDD를 함께 사용할 때, 전통적인 Spring 기반의 계층 구조 대신 DDD의 개념을 반영한 구조를 적용할 수 있습니다. 

 

일반적으로 다음과 같은 구성 요소로 구성됩니다.

 

도메인 모델(Domain Model):
DDD에서 도메인 모델은 애플리케이션의 핵심이 되는 비즈니스 도메인을 나타내는 객체입니다. 도메인 모델은 도메인의 개념과 규칙을 캡슐화하고, 
비즈니스 로직을 처리하는 책임을 갖습니다. Spring Boot에서는 도메인 모델을 일반적인 Java 클래스로 표현할 수 있습니다.

 

리포지토리(Repository):
리포지토리는 도메인 객체를 영구 저장소에 저장하고 검색하기 위한 인터페이스입니다. 
Spring Boot에서는 리포지토리를 인터페이스로 정의하고, Spring Data JPA 등의 기술을 사용하여 데이터베이스와의 상호작용을 구현할 수 있습니다.

 

애플리케이션 서비스(Application Service):
애플리케이션 서비스는 도메인 모델 사이의 상호작용을 조정하고, 도메인 객체의 상태 변경을 처리합니다. 
Spring Boot에서는 애플리케이션 서비스를 일반적인 Spring Bean으로 구현할 수 있습니다.

 

인프라스트럭처(Infrastructure):
인프라스트럭처는 데이터베이스, 외부 서비스, 메시징 시스템 등과의 상호작용을 담당합니다. 
Spring Boot에서는 데이터베이스 연결, 메시지 브로커 설정 등을 위해 Spring의 기능을 사용할 수 있습니다.

  • DDD 주요 레퍼런스
  1. Amazon: Amazon은 대규모 분산 시스템 및 마이크로서비스 아키텍처를 구축하는데 Spring Boot와 DDD 구조를 활용하고 있습니다. Amazon의 여러 서비스와 플랫폼 중에서도 AWS(Amazon Web Services)는 Spring Boot와 DDD를 사용하여 개발되었습니다.
  2. Netflix: Netflix는 Spring Boot와 DDD 구조를 사용하여 대규모 온디맨드 비디오 스트리밍 플랫폼을 개발하고 운영합니다. Netflix의 다양한 마이크로서비스는 도메인 모델과 DDD의 원칙에 따라 설계되었으며, Spring Boot를 통해 개발 및 배포되고 있습니다.
  3. Microsoft: Microsoft는 Spring Boot와 DDD 구조를 사용하여 클라우드 서비스, 기업 애플리케이션, 인프라스트럭처 관리 도구 등 다양한 솔루션을 개발하고 있습니다. Azure를 통해 Spring Boot와 DDD를 사용하여 개발된 애플리케이션을 구축할 수 있습니다.
  4. 현대자동차그룹: 현대자동차그룹은 Spring Boot와 DDD 구조를 활용하여 자동차 관련 애플리케이션과 서비스를 개발하는데 사용하고 있습니다. 현대자동차그룹은 DDD의 주요 원칙을 적용하면서 도메인 모델을 중심으로 한 애플리케이션 아키텍처를 구축하고 있습니다.

 

JAVA는 객체 지향 프로그래밍 언어로, 플랫폼에 독립적인 언어라는 특징이 있다.

 

자바 컴파일러는 CLASS파일을 생성하고 이 파일의 바이트코드를 읽은 뒤 자바 가상머신에서 기계어로 바꾸어 실행하기 때문에 윈도우, 리눅스, 맥OS등 OS에 구분없이 잘 작동합니다.

 

요즘 개발언어로 각광받고 있는 Python, Ruby를 순수 객체지향이라 부르는데, JAVA는 모든 것을 객체로 보는 언어는 아니다. *원시타입(Primitive)은 객체로 보지 않음

 

객체 지향 프로그래밍을 잠깐 설명하자면, 작은 문제들을 해결할 수 있는 객체들을 만든 후 객체들을 조합해서 큰 문제를 해결하는 상향식 해결법을 도입해서 만든 것으로 이런 객체들은 만들어 놓기만 하면 재사용이 가능하다는 장점이 있다.

 

객체 지향 프로그래밍 언어는 요소로는 캡슐화 (변수와 함수를 하나의 단위로 묶는 것), 상속(자식 클래스는 부모 클래스의 특성 & 기능을 물려받아서 사용한다는 것, 캡슐화를 유지하면서 클래스 재사용이 용이하게 해준다.), 다형성(서브타입, 매개변수, 임시, 강제)등이 있다.

  • 다형성 부분은 서적을 통해서 읽어보시면 개발하실 때 반드시 도움이 되실 것입니다.

 

웹 애플리케이션 제작을 위해서 사용하는 규격은 JAVA 서블릿과 JSP(Java 서버 페이지)가 있다.  닷넷으로 치면 서블릿이 .cs(로직), jsp가 .aspx페이지(화면)

 

JDK(Java Development Kit)로 설치를 하면 javac라는 컴파일러를 제공하지만 따로 개발환경을 해주지 않기 때문에! 

 

이클립스, Intellij와 같은 프로그램을 설치해서 사용해야 한다.

 

프로젝트에 필요한 라이브러리나 빌드 관리 도구는 maven, gradle이 많이 채용된다.

 

오라클에서 제공하는 버전은 요즘 유료화 되어, 기업에서 사용 시 OpenJDK를 사용하는 것이 일반적인 추세이다.

 

JAVA에서 사용하는 웹 프레임워크는 대표적으로 스트럿츠(STRUTS), 스프링(Spring)가 있다.

 

JAVA로 웹 서버를 개발하면 대부분 Spring에서 만든다고 생각하시면 되는데, 구조는 아래와 같습니다. 

 

 

Spirng의 특징은 아래와 같습니다.

  • Spring은 자바 객체와 라이브러리들을 관리해주며, 톰캣과 같은 WAS 가 내장되어 있어 자바 웹 어플리케이션을 구동할 수 있습니다.
  • Spring은 경량 컨테이너로 자바 객체를 직접 Spring 안에서 관리합니다. 객체의 생성 및 소멸과 같은 생명 주기(Life cycle)을 관리하며, Spring 컨테이너에서 필요한 객체를 가져와 사용합니다.
  • 제어의 역전(IOC , Inversion Of Control) : 클래스 내부의 객체 생성 -> 의존성 객체의 메소드 호출이 아닌, 스프링에게 제어를 위임하여 스프링이 만든 객체를 주입 -> 의존성 객체의 메소드 호출 구조입니다. 스프링에서는 모든 의존성 객체를 스프링이 실행될때 만들어주고 필요한 곳에 주입해줍니다.
  • 의존성 주입(DI, Dependency Injection) : 어떤 객체(B)를 사용하는 주체(A)가 객체(B)를 직접 생성하는게 아니라 객체를 외부(Spring)에서 생성해서 사용하려는 주체 객체(A)에 주입시켜주는 방식입니다. 사용하는 주체(A)가 사용하려는 객체(B)를 직접 생성하는 경우 의존성(변경사항이 있는 경우 서로에게 영향을 많이 준다)이 높아집니다. 하지만, 외부(Spring)에서 직접 생성하여 관리하는 경우에는 A와 B의 의존성이 줄어듭니다.
  • AOP (Aspect Oriented Programming) 관점 지향 프로그래밍 지원 
  • POJO(Plain Old Java Object)방식으로 자바객체는 특정한 인터페이스를 구현하고 클라스 상속이 필요치 않습니다. (참조 사이트 : https://velog.io/@galaxy/Spring%EC%9D%98-%EA%B8%B0%EB%B3%B8-%ED%8A%B9%EC%A7%95-POJO)
  • 트랜젝션 처리를 위한 일관된 방법을 제공합니다.
  • 영속성 관련 다양한 API를 지원합니다.
  • API연동을 지원합니다.

 

스프링 개념 

(참조 사이트 : https://life-with-coding.tistory.com/412)

 

Spring Boot는 Spring Framework 기반 프로젝트를 쉽고 빠르게 만들어주는 라이브러리라고 생각하시면 편합니다. (스프링 프레임워크를 보다 쉽게 셋팅할 수 있게 해줌)

 

Spring Framework로 셋팅할려면 기존에는 개발자가 모든 것을 셋팅해야 했는데, (ibatis, mybatis, dbcp, logback, log4j, maven, gradle, mvc servlet, mvc interceptor, spring security등등)

 

이런 복잡한 설정을 대부분 미리 셋팅해 놓아 바로 웹 개발에 들어갈 수 있도록 했다.

 

SPRING BOOT가 나오기 전에는 프로젝트를 진행할 때 기존 프로젝트 사용설정을 복붙하고 필요한 것은 다시 셋팅해주는 번거로움이 있었는데 이를 대체한 것이다.

 

Spring Boot는 이외에도 많은 장점이 있는데, Spring 라이브러리와 third party 라이브러리 버전을 자동으로 관리해주는 기능이라던지, tomcat을 내장하고 있으며, war가 아닌 jar로 패키징이 가능하고, starter 라이브러리를 등록하여 의존성을 간단히 관리할 수 있다.

한글이 깨지면 화가난다.

 

방법 1. html 요소에 아래 코드 삽입

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">

방법 2. jsp 상단에 아래 코드 삽입

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

방법 3. IDE(이클립스, 인텔리제이, 비쥬얼스튜디오)에 인코딩을 UTF-8로 변경

 

3가지 방법으로 앵간하면 해결된다.

 

컨트롤러에서 여러 개의 INSERT, UPDATE, DELETE가 일어날 경우 Transactional 어노테이션을 사용하여 정합성을 맞출려고 할 때가 있다.

 

이 때 @Autowired를 쓰지 않고 서비스를 final로 선언을 하면 에러가 난다.

 

오늘 이걸로 4시간동안 헤맸다..

 

기억하자 ! 

 

이번에 포스팅할 내용은 SSL 적용이다. 

 

SSL은 Secure Socket Layer이라는 약자로 보안 소켓 레이어이다.

 

보통 443포트를 사용하며 https:// 를 사용한다.

 

쓰는 이유를 물어보면 보안과 SEO로 나눌 수 있다.

 

적용 시 보안적으로는 안정적인 통신을 보장해주고, SEO적으로는 구글에서 검색순위를 높게 측정한다고 한다.

 

단점으로는 SSL인증서를 발급받아 적용해야 하는데 이 인증서는 매년 갱신해주어야 하며, 공짜가 아니다. 

 

한마디로 돈이 들어간다. 

 

그리고 아주 기초적인 수준의 개발실력이 있어야 적용할 수 있다. 

 

이번에 소개할 Sectigo SSL 인증서는 비교적 저렴하게 사용할 수 있어서 사용했다.

 

수 많은 대행사이트에서 이 인증서를 사용하는데, 

 

쌀수록 설명이나 사후지원이 약하고, 비쌀수록 그런 부분이 잘 되는 정도의 차이가 있는 것 같이 보였다.

 

이 글을 보는 분들은 다 직접 결국 세팅을 하실 것이기 때문에 (그렇게 만들 것이기 때문에..) 

 

개인적으로는 싼 게 좋아보인다.

 

* secure sign 사이트가 저렴하다. 

* www.securesign.kr/

 

SSL 인증서 국내 최저가 Sectigo Comodo GeoTrust Thawte RapidSSL - SecureSign

글로벌 SSL 인증서 최저가 발급. 와일드카드, 멀티도메인. CSR 자동 생성. PEM, PFX, JKS 포맷 제공. 재발급 무제한. 서버 무제한 설치. 모바일지원. 간편인증, SecureSign, SSLCERT

www.securesign.kr

 

더 저렴한 사이트도 분명 있을 것이다. 

 

나름 덩치가 커진 supercup 사이트는 가비아에서 구매했는데, securesign사이트에 비하면 4배정도 비쌌다..

 

배상금 정책같은 소소한 차이가 있을 것이므로 인증서도 잘 살펴보고 사자..

 

* 가비아든 securesign이든 어떤 곳이든 발급기관이랑 무관하게 SSL 적용은 전체적으로 아래와 같다.

 

자 이제 사설은 여기까지 하고 적용하는 법을 보자~

 

 

1번째. 인증에 사용할 JKS(Java Keystore) 파일을 생성한다.

 

keytool -keysize 2048 -genkey -alias scup -keystore 경로/scup.jks -keyalg RSA

* scup은 개인키의 별칭이다 아무거나 입력해줘도 된다. 

 

앞으로 쓸 비밀번호를 2번 입력한 후 첫 입력창으로 이름을 말하라고 할 때 사이트 주소를 입력해야 한다.

(http,https를 제외한 사이트 도메인만) 

 

 

마지막엔 국가코드 KR을 입력하면 된다 

 

- Country (C) : 국가코드, 대문자로 입력해야 합니다. (한국 : KR)
- State (ST) : 시/도
- Locality (L) : 구/군
- Organization (O) : 회사명
- Organization Unit (OU) : 부서명
- Common Name (CN) : 인증서 도메인 주소를 입력합니다. 와일드카드 인증서는 *.도메인을 입력합니다. 

 

다 입력한 후 맞냐고 여쭤볼때 y로 맞다고 입력하고 비밀번호 확인 시 그냥 enter를 누르고 넘어가자.

 

개인적으로는 인증서 폴더를 따로 만들어서 이런식으로 명령어를 쳤다.

mkdir cert
cd cert
keytool -keysize 2048 -genkey -alias superbalance -keystore superbalance.jks -keyalg RSA

* superbalance는 개인키의 별칭이다. 

 

 

2번째. csr파일을 만들자.  

csr파일 내용을 가비아나 securesign사이트를 제출해야 한다.

 

keytool -certreq -keyalg RSA -alias superbalance -file superbalance.csr -keystore superbalance.jks

 

이렇게 만들어진 csr을 vi로 열어서 보던지, 파일질라로 notepad++이나, 메모장으로 열어서 보면

 

-----BEGIN NEW CERTIFICATE REQUEST-----
******

***

**

**

**

-----END NEW CERTIFICATE REQUEST-----

 

이런식으로 적혀있다. 안에 내용은 *로 대체했다. 

 

주석까지 싹 긁어서 제출을 하면 된다. 

* 제출 시 인증방법을 메일로 하자. 나머지 방법으로는 안해봐서 모르겠다 !!

 

3번째. 인증을 하자

 

그렇게 SSL 인증서를 신청하면 sectigo에서 인증 메일이 온다. (물론 신청 시 결제도 해야된다.. 유료예요)

* 인증 메일이 오는 데 시간이 좀 걸릴 수 있다. (securesign은 3분 안, 가비아는 40분정도 걸렸다.)

 

메일 중앙에 있는 인증코드를 복사한 후 here버튼을 누른 뒤 복사한 인증코드를 입력하면 인증이 된다.

 

4번째. 인증서 파일을 다운로드하고 import하자

 

그 후 발행 사이트(가비아 등등)에서 내 정보를 확인하면 인증서 파일을 받을 수 있다. 

(* 이건 거의 바로 된다. 지체되면 2-3분 정도는 걸릴 수도 있다.)

 

인증서 파일 구성은 이렇다.

----------------------

Root인증서 

Chain1번 인증서

Chain2번 인증서
SSL 인증서

----------------------

 

깨알같이 Root+Chain1번+Chain2번 이렇게 합쳐진 인증서를 줘서 한 번만 import하도록 해주던데

 

그냥 정석으로 각 파일마다 import하자. 맘 편한 게 정석이니까..

 

SSL 인증서는 거의 확장자가 pem이고 나머지 인증서는 crt이거나 pem이었다. 

루트 - 체인 1 - 체인 2 - SSL 인증서 순으로 jks파일에 import해주자

 

체인 3번이 있으면 SSL 인증서 전에 체인 3번도 넣어주자.

 

keytool -import -alias root -keystore superbalance.jks -trustcacerts -file AAACertificateServicesRoot.crt.pem
keytool -import -alias chain1 -keystore superbalance.jks -trustcacerts -file USERTrustRSACertificationAuthorityChain1.crt.pem
keytool -import -alias chain2 -keystore superbalance.jks -trustcacerts -file SectigoRSADomainValidationChain2.crt.pem
keytool -import -alias superbalance -keystore superbalance.jks -file superbalance.co.kr_20201209L4Z7.crt.pem

위의 예제는 루트 - 체인 1 - 체인 2 - SSL 인증서 순으로 jks파일에 import한 것이다.

 

루트 인증서를 import할 때 이미 있다는 식으로 뜨는데 그냥 y 누르고 넘어가면 된다.

 

자 이제 SSL인증서가 import된 jks파일은 준비가 되었다. 

 

 

5번째. Tomcat 셋팅

 

돈도 들여가며 어렵사리 준비한 jks파일을 톰캣에 셋팅하자. 

 

클라우드 서비스를 쓰시는 분들은 (AWS, GCP, AZURE) SSL용으로 쓸 443포트를 미리 열어두자.

 

tomcat이 설치된 디렉토리로 들어가서 conf폴더에 server.xml을 열자

 

HTTPS 프로토콜을 사용하기 위해 Connector 설정을 해주자.

 

 <Connector
                URIEncoding="UTF-8"
                compressableMimeType="text/html,text/xml,text/plain,text/javascript,text/css,application/javascript"
                compression="on"
                compressionMinSize="2048"
                noCompressionUserAgents="gozilla, traviata"
                port="80" protocol="HTTP/1.1"
                connectionTimeout="20000"
                redirectPort="443" />
    
   <Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
                   port="443" SSLEnabled="true" maxThreads="200"
                   scheme="https" secure="true"
                   keystoreFile="$경로/$파일명.jks"
                   keystorePass="$비밀번호" clientAuth="false"
                   sslProtocol="TLS" />

    
    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="8009" protocol="AJP/1.3" redirectPort="443" URIEncoding="UTF-8"/>

 

$경로, $파일명, $비밀번호에 본인이 셋팅한 값을 넣자 ~ 

 

이렇게 톰캣을 내렸다 올리면, https가 적용이 된다.

 

물론 http도 된다. 

 

http로 접근하면 https로 바뀌게 프로젝트 셋팅을 바꿔보자 ~ 

 

 

6번째. 프로젝트 셋팅(spring)

 

6-1)web.xml을 수정하자!

<filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

..
..

<servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                classpath:/spring/security-config.xml
            </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

..
..

<security-constraint>
	    <web-resource-collection>
	        <web-resource-name>SSL Forward</web-resource-name>
	        <url-pattern>/*</url-pattern>
	    </web-resource-collection>
	    <user-data-constraint>
	        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
	    </user-data-constraint>
	</security-constraint>

</web-app>

HTTPS로 붙도록 수정해주자.

그리고 security-config.xml을 참조하도록 수정!

maven이나 gradlel로 spring security쪽을 가져오자~

 

security-config.xml쪽도 수정하자.

 

<?xml version="1.0" encoding="UTF-8"?>

<beans:beans xmlns="http://www.springframework.org/schema/security"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:aop="http://www.springframework.org/schema/aop"
             xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
		http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">

	

    <http auto-config="true" use-expressions="true" create-session="never">

		 <intercept-url pattern="/**" requires-channel="https" access="permitAll" />

...
...

</beans:beans>

 

 

이러면 모두 끝났다 ~ 

사이트에 접근했을 때 상단에 자물쇠 마크가 정상적으로 보이면 성공!

superbalance.co.kr/

 

황금 밸런스 게임 - SuperBalance

황금 밸런스 게임을 직접 플레이하고 만들어보세요 ~

superbalance.co.kr

 

머니머신에 관심이 갖고 지낸지 1년 반 정도가 지나간다. 

 

나는 머니머신을 다양하게 만들었다. (사이트/유튜브/티스토리/네이버블로그) 

 

수익을 주었던 광고매체 3가지를 비교해보겠다.

 

1. 애드센스 (구글)

- 애드센스가 그냥 갑이다. 그냥 다른 말로 설명할 필요가 없다.

 

사이트를 만들고 유튜브를 하고 블로그를 하고, 다들 이유가 있겠지만, 

 

가장 중요한 건 '수익', 즉 돈이라고 생각한다.

 

그럼 광고매체중에서 가장 수익이 좋은 건? 애드센스다. 

 

내 수익의 대부분은 내가 만든 사이트에서 발생한다. (이상형 월드컵 사이트다)

 

http://supercup.co.kr/

 

아이돌 움짤, 여자 IDOL 이상형 월드컵, 이상형 월드컵 게임, 이상형 월드컵 통계 SUPERCUP, 이상형만

공식적인 이상형 월드컵 사이트 - SUPERCUP입니다. 이상형 월드컵을 만들어서 즐겨보세요

supercup.co.kr

그리고 유튜브 광고 수익도 애드센스로 지급된다.

 

깨알같은 유튜브 채널 소개 (이상형 월드컵 순위랑 매력적인 분들에 대한 인물탐구를 주로 다루고 있다.)

https://www.youtube.com/channel/UCTV-jni1LLGSu1ATBdhN3iQ/

 

말맹튜브

매력적인 인물의 인물탐구와 이상형월드컵 사이트 supercup의 순위를 즐기세요 :)

www.youtube.com

 

각설하고 애드센스의 장단점을 말하면..

 

<장점>

- 클릭 당 단가가 높고 일정하다. (광고를 누르면 주는 돈이 세다)

 

- 편하다 (자동광고 게재)

 

- 모바일/PC 반응형으로 잘 나온다 (애드핏도 요즘 잘 나온다)

 

- 애드몹/유튜브와 연계가 된다.

 

- 티스토리와 연계가 가능하다. 

 

- 돈이 달러로 쌓이기 때문에 환율이 오를 때 짭짤하다

 

- 칼 같이 입금된다.

 

<단점>

- 심사가 까다롭다. (애드센스 고시가 괜히 있는 말이 아님, 내 사이트도 2번 낙방했다)

 

- PIN번호가 오는 데 오래 걸린다 (45일정도 걸린 거 같다.)

 

- 탑툰/미툰 등 성인웹툰 광고가 많이 뜬다. (걸러도 걸러도 계~속 나옴)

 

- 돈을 달러로 주기 때문에 환율이 떨어질 때 씁쓸하다.

 

- 수익을 지급 받을 때 과정이 좀 복잡할 수 있다. (해외 통장을 뚫어야 한다.)

 

블로그와 사이트 운영하시는 분들은 무조건 애드센스 광고 먼저 도전하는 게 좋다. 

 

빨리 도전해야 낙방해도 보완해서 다시 시도할 수 있다. 

 

애드센스가 그만큼 독보적이다.

 

 

 

2. 애드핏 (카카오)

애드핏은 카카오에서 만든 광고 플랫폼이다.

 

국내에 있는 다른 광고보다 젤 낫다. 광고매체계의 2인자다.

 

다른 광고플랫폼은 거들떠 볼 필요가 없을 정도로 압도적이다. 2인자일뿐..

 

<장점>

- 심사가 까다롭지 않다. 

 

- 심사가 통과된 이후 하루내에 광고 적용이 가능하다. (빠르다/쉽다)

 

- 장점 중에 이게 젤 핵심인데, 광고 노출 당 비용이 세다. (즉, 광고를 클릭하지 않아도 주는 비용이 애드센스보다 낫다.)

 

- 광고단위 만드는 게 간단하다. 

 

<단점>

- 클릭 당 단가가 약하다. (애드센스가 센 건지, 애드핏이 약한 건지..)

 

- 가끔 광고가 안 나온다. (이건 시스템상의 문젠지, 너무 광고를 자주 호출되니까 막는건지 잘 알 수가 없음)

 

- 시스템이 조금 이상한데 수익 지급이 느린 편이다. (2월 수익을 4월에 받을 수 있음)

 

애드센스만 사용하는 사이트 운영자와 블로거들도 있을 텐데, 애드핏이랑 같이 쓰는 것도 나쁘지 않다.

 

애드핏은 일단 고정적으로 수익이 보장된다. (유저수만 확보하면)

 

애드센스의 훌륭한 대체재이다. 

 

 

3. 애드포스트(네이버)

네이버 블로그를 운영하면서 적용하고 있는 애드포스트다.

 

네이버 블로그는 그냥 이상형 월드컵 순위 알리는 용도로 운영중이라, 일 방문자가 많지는 않다.

 

장단점을 쓸만큼 오랫동안 운영하진 못헀지만.. 써보면..

 

<장점>

- 심사가 거의 없는 수준이다. 

 

- 간단히 적용 가능하다. 

 

- 가끔 로또금액이 터진다. (하루에 3072원의 수익이 발생한 적이 있었다. 평균 10-20원)

 

<단점>

- 전문 블로거가 아니면 걍 돈이 안된다.

 

- 네이버 블로그에 적용하는 것 말곤 메리트가 없다.

 

- 네이버 포인트로 수익을 지급한다. (네이버쇼핑에 사용할 수 있어서, 불만은 없다.)

 

결론만 말하면, 블로그나 사이트를 운영하시는 분들은 애드센스를 주력으로, 애드핏을 서브로 가져가는 게 제일 좋다.

 

그리고, 네이버 블로그를 운영하시는 분들만 애드포스트를 설치해서 수익을 얻자.

 

마지막으로, 애드몹도 연동할려고 한다. 즉 앱으로도 머니머신을 넓힐 생각이다.

 

목표는 나중에 내가 몸이 아파서 일을 못하게 되더라도 나를 먹여살려줄 시스템을 구축하려고 하고, 구축할 것이다. 

 

 

 

+ Recent posts