반응형


Spring boot 에서  Invisible reCAPTCHA 설정하는 방법이다.



reCAPTHA 는 쉽게 말해 봇이 접근을 시도하는 것으로부터 보호하여 스팸글 등록 및 자동 글 작성 자동 회원가입을 막는 것이다.


현재는 v3까지 나왔으며 여러버전이 있는 데, Invisible reCAPTCHA는 말그대로 보이지 않는다. 버튼 체크나, 그림 맞추기 등을 하지 않아도 됨.

원리는 구글측에서 공개하지는 않았지만 구글측에서 사용자의 패턴을 분석해서 방지한다는 정도로 알고있다.



1.  https://www.google.com/recaptcha/intro/v3.html 사이트에 접속한다.


우측 상단의 My reCAPTCHA에 접속한다.



2.  접속한 뒤 새로 만든다.


Label 에는 제목을 입력한다. 이 제목은 말그대로 그냥 제목이다 파일 이름 짓듯이, 프로젝트 생성하듯이 지으면 된다.

그리고 아래와 같이 기입한 후 생성한다. Send alerts to owner는 체크해도 되고 안해도된다. 그리고 만들고나서도 수정 가능하니 신경을 크게 안써도 된다.



3.  생성된 것을 확인

아래와 같이 Site key와 Secret key를 받게 된다.

Step1에는 사용방법이 간단하게 나와 있으며 

Step2에는 Invisible reCAPTCHA API에 사용에 필요한 요청과 응답이 나와 있다.


4.   https://developers.google.com/recaptcha/docs/invisible 옆의 주소에 들어간다.

구글에서 아래와 같이 기본적인 예제를 올려 놓았다. 

이것을 복사를 한다.



5. 복사를 했으면 Spring boot의 static 폴더 아래에 아래와 같이 만든다

굳이 여기가 아니더라도 프론트엔드를 따로 사용하시는 분들이라면 그 쪽에 만들어서 사용하면 된다.


data-siteKey는 3번에서 받은 Site-key를 입력한다. 그리고 action에는 reCAPTCHA에 사용할 API주소를 입력한다. 


6. action에 사용할  reCAPTCHA를 사용할 Controller를 만든다.

하지만 그 전에 reCAPTCHAP에 응답받을 DTO를 생성한다. 이 작업은 굳이 안해도 되고 String으로 바로 받아도 되지만

깔끔함을 위해 작성했다.

구글 API에 아래와 같이 나와있다. 

위를 바탕으로 DTO를 작성한다.

public class reCAPTCHA_DTO {
	private boolean success;
	private Integer number;
	private String action;
	private String challenge_ts;
	private String hostname;
	private String error_codes;
	
	
	public reCAPTCHA_DTO() {
		super();
	}


	public reCAPTCHA_DTO(boolean success, Integer number, String action, String challenge_ts, String hostname,
			String error_codes) {
		super();
		this.success = success;
		this.number = number;
		this.action = action;
		this.challenge_ts = challenge_ts;
		this.hostname = hostname;
		this.error_codes = error_codes;
	}


	public boolean isSuccess() {
		return success;
	}


	public void setSuccess(boolean success) {
		this.success = success;
	}


	public Integer getNumber() {
		return number;
	}


	public void setNumber(Integer number) {
		this.number = number;
	}


	public String getAction() {
		return action;
	}


	public void setAction(String action) {
		this.action = action;
	}


	public String getChallenge_ts() {
		return challenge_ts;
	}


	public void setChallenge_ts(String challenge_ts) {
		this.challenge_ts = challenge_ts;
	}


	public String getHostname() {
		return hostname;
	}


	public void setHostname(String hostname) {
		this.hostname = hostname;
	}


	public String getError_codes() {
		return error_codes;
	}


	public void setError_codes(String error_codes) {
		this.error_codes = error_codes;
	}
}

7. 이제 controller를 작성한다.


params 의 seceret에서는 3번의 seceret_key를 적는다.

3번에의 요청에서 봤듯이 ip가 필요하기 때문에 ip를 받아온다. (ip받아오는 방법은 서버마다 다르기 때문에 굳이 이렇게 안해도 됨.)

g-recaptha-response역시 3번에 나와 있듯이 구글측에서 주는 것이기 때문에 RequsetParam으로 받아 그대로 사용하면 된다.

그리고 아래와 같이 작성해서 post를 날리면 된다.


@PostMapping() public reCAPTCHA_DTO reCAPTCHA_TEST(@RequestParam(name="g-recaptcha-response") String recaptchaResponse , HttpServletRequest request) { String ip = request.getRemoteAddr(); String url = "https://www.google.com/recaptcha/api/siteverify"; String params="?secret=6LcwQYIUAAA******************&response="+recaptchaResponse; RestTemplate restTemplate = new RestTemplate(); reCAPTCHA_DTO re = restTemplate.exchange(url+params, HttpMethod.POST, null, reCAPTCHA_DTO.class).getBody(); if(re.isSuccess()) { System.out.println("성공"); } else { System.out.println("실패"); } return re; }

8. 결과


아래 사진과 같이 맨 오른쪽 하단에 reCAPTCHA 표시가 나타나며 submit을 누르면 결과가나온다.

결과



Invisible reCAPTCHA말고도 다른 reCAPTCHA사용하는 방법 역시 위와 크게 다르지 않기 때문에 아래의 레퍼런스에서 확인하여 때에 맞게 사용하면 된다.



참고 -  https://developers.google.com/recaptcha/intro

반응형
반응형


먼저 이 글을 보기 전에 알고 있으면 더 좋은 글입니다.


1번. MySQL JSON DATA TYPE

2018/11/30 - [Develop/MySQL] - [MySQL] MySQL JSON - MySQL 5.7 JSON Functions



2번. MySQL에서의 '일반' 값을 JSON형식으로 가져오기

2018/10/28 - [Develop/Spring Boot] - Spring boot JPA EntityManager를 이용한 Map형식으로 mapping하기

2018/10/24 - [Develop/Spring Boot] - Spring boot jpa map, hashmap, JSON형식


3번. JSON PARSING

2018/11/13 - [Develop/Spring Boot] - Spring Boot Json, hashmap to json , JsonObject 만들기- JSON 마지막

2018/11/12 - [Develop/Spring Boot] - Spring Boot Deserialization Json, Deserialization JsonString to JsonObject - Json 4편

2018/11/09 - [Develop/Spring Boot] - Spring Boot Json, Jackson을 이용한 JsonParsing - Json 3편

2018/11/07 - [Develop/Spring Boot] - Spring Boot Json, Gson을 이용한 JsonObject to String, String to JsonObject- JSON 2편

2018/11/06 - [Develop/Spring Boot] - Spring Boot Json, JsonObject로 만들기 - JSON 1편



나도 SPRING BOOT 에서 어떻게 가져오는지 많이 검색해봤으나. 자료가 거의 없어서 열심히 삽질했던 것 같다.

수 많은 삽질 끝에 알아내서 필요한 곳에 사용중이다.


이번 글은 MySQL에서 SELECT시 일반 DATA 형식이 아닌 JSON DATA TYPE을 SPRING BOOT 에 SELECT하는 내용이다.

우선 일반 DATA형식은 그냥 말그대로 SELECT id, name FROM test 해서 가져오는 내용들이고

JSON DATA TYPE 형식은 위의 1번 링크에서 확인할 수 있다.



1. 우선 이번에 사용할 예제 테이블 및 데이터이다. 1번링크에서 확인 가능하다.



2. 먼저 JSON DATA TYPE을 불러올 코드를 작성한다.


아래의 코드를 보면 CONCAT_WS('\\\\',  부분이 있다.


사실 JSON DATA TYPE을 가져올 때 JSON_OBJECT를 사용하면 가져올 수 있으나. 사용하는 이유는


SPRING BOOT에서 CONCAT_WS('\\\\',  를 사용하지 않으면 MySQL에서 값을 불러올때 쌍따옴표를 지워버린다. 


그래서 만약 CONCAT_WS를 사용하지않고 JSON_OBJECT만을 이용하여 SELECT하면


ex) {"ID": 1, "NAME": "TEST", "PASSWORD": "1234", "PHONE_NUM": "010-1111-1111"} 이렇게 불러와야할 값이

     {"    이렇게 나오고 뒤의 내용은 다 짤려버린다.


그래서 CONCAT_WS 함수를 이용하여 쌍따옴표가 안짤리고 SELECT하기 위해 앞에 역슬래쉬를 붙인다. 


4개 붙이는 이유는 두개 붙이니까 SPRING BOOT단에서 짤려버리더라...... 그래서 4개 붙인다.


그리고 CONCAT_WS를 사용하면 값을 Byte로 불러온다.  그래서 String 형식이나 기타 외의 데이터로는 불러오지 못하므로


항상 Object 데이터 형식을 사용해서 불러와야 한다. 그 후 Object를 Byte로 변환 그리고 Byte를  String으로 변환하는 방법 등을 사용 해야 한다.


아래의 코드에서도 우선 List로 결과를 불러오고 Object를 통해 Byte로 변환 그리고 Byte를 다시 String으로 변환한다.


@GetMapping("/test")
	public void test() {
		Query query = entityManager.createNativeQuery("SELECT " + "concat_ws('\\\\', "
				+ "json_object('id', t.id, 'password', t.password, 'name', t.name, 'phone_num', t.phone_num)) "
				+ "as TEST " + "FROM " + "test t");

		List r = query.getResultList();
		for (Object obj : r) {
			byte[] b = (byte[]) obj;
			String value = new String(b, StandardCharsets.UTF_8);
			System.out.println(value);
		}
}


위 코드를 실행하면 아래와 같은 JSON 타입의 내용을 Spring Boot에서 불러올 수 있다.




3.  이 Json String을 JsonObject로 만들어보자 


3번 링크의 Gson이나 Jackson, JsonObject 등등 을 이용하여 만들 수 있다.


Jackson을 이용하여 한번 만들어 보겠다.


먼저 TestDTO 클래스를 하나 만든다 

3번링크의 Json 1편의 DTO에서 password와 phone_num 변수를 추가한다.


만든 후 현재 데이터를 2개가 불러오기 때문에 객체 배열로 생성하였다.

그 후 각 클래스 배열마다 Jackson의 objectmapper를 사용하여 Json String을 Json Object로 변환시켜주었다.


Query query = entityManager.createNativeQuery("SELECT " + "concat_ws('\\\\', "
				+ "json_object('id', t.id, 'password', t.password, 'name', t.name, 'phone_num', t.phone_num)) "
				+ "as TEST " + "FROM " + "test t");


		List r = query.getResultList();
		
		ObjectMapper objectMapper = new ObjectMapper();
		TestDTO t[] = new TestDTO[r.size()];
		int i=0;
		
		for (Object obj : r) {
			byte[] b = (byte[]) obj;
			String value = new String(b, StandardCharsets.UTF_8);
			try {
				
				t[i]= objectMapper.readValue(value, TestDTO.class);
				i++;
			}
			catch (IOException e) {
				e.printStackTrace();
			}
		}
		for(TestDTO test : t) {
			System.out.println(test.getId());
			System.out.println(test.getPassword());
			System.out.println(test.getName());
			System.out.println(test.getPhone_num());
			System.out.println();
		}

아래와 같이 결과가 나온다


이것을 많은 형식을 이용하여 불러 올 수있다 2번링크를 사용하여 애초에  Map으로 불러와서 mapping시키거나 할 수 있다.


Map으로 불러와서 mapping할 경우 문제점은 정규식을 통해 파싱해줘야 하는 단점이있다.


왜냐하면 Json값이 { "id" : 1 } 이렇다면 Map으로 불러올경우 "{ "id" : 1 }" 이렇게 중괄호에 쌍따옴표가 붙어버린다.


그래서 정규식을 통해 중괄호의 쌍따옴표만 지워야 하는 단점이 있다. 하지만 나는 이러한 단점에도 불구하고도 


JSON_TYPE과 함께 일반 데이터까지 가지의 값을 가져 와야하기 때문에 자주 사용한다.

반응형
반응형


MySQL 5.7.8 VER 부터 JSON TYPE을 지원해준다. 

그래서 MySQL에서 JSON TYPE을 위한 많은 함수를 제공해준다.


MySQL에서는  JSON Functions의 레퍼런스를 상세히 제공해준다.


MySQL 5.7 : https://dev.mysql.com/doc/refman/5.7/en/json-functions.html
MySQL 8 : https://dev.mysql.com/doc/refman/8.0/en/json.html

아주 기본적인 예만 한번 해본다.

1.TEST라는 이름을 가진 테이블안에 아래와 같은 2개의 데이터가 들어가 있다.


2.  MySQL 레퍼런스에서 제공해주는 JSON_OBJECT라는 Function을 사용하면

아래와 같은 결과를 얻을 수 있다.



{
    "ID":  1,
     "NAME":  "TEST",
     "PASSWORD":  "1234",
     "PHONE_NUM":  "010-1111-1111"
}{
    "ID":  2,
     "NAME":  "HI",
     "PASSWORD":  "5555",
     "PHONE_NUM":  "010-2222-2222"
}


반응형

+ Recent posts