1. 로그인 페이지 만들기! 

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
	<title>Home</title>
	<script src="https://developers.kakao.com/sdk/js/kakao.min.js"></script>
</head>
<body>

  
    <h1>로그인</h1>
    <hr>

    <form action="/user/login" method="post">
        <input type="text" name="username" placeholder="이메일 입력해주세요">
        <input type="password" name="password" placeholder="비밀번호">
        <button type="submit">로그인</button>
        
        
  		<a href="http://developers.kakao.com/logout"></a>
  		
    </form>
    
	<a href="https://kauth.kakao.com/oauth/authorize?client_id={클라이언트키}&redirect_uri={리다이렉트 url}&response_type=code">로그인</a>
	<a href="https://kauth.kakao.com/oauth/authorize?response_type=code&client_id={클라이언트아이디}&scope=profile,account_email&state=Z3JNGXqbBZCtif_8D0hz5hWhuAeftMPNUIeCOW4_Kj4%3D&redirect_uri={리다이렉트 url}">동의</a>
    
    
    <script src="/resources/css/bower_components/jquery/dist/jquery.min.js"></script>
	<script src="/resources/css/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
	<script src="/resources/css/dist/js/adminlte.min.js"></script>
	<script src="/resources/js/utils/easy_ui/jquery.easyui.min.js"></script>
   

   
</body>
</html>


 

 

controller 

import java.util.HashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.me.genie.service.KakaoService;

@Controller
public class KakaoController {
	
	@Autowired private KakaoService kakaoService;
	
	@RequestMapping("/login")
    public String home(@RequestParam(value = "code", required = false) String code, Model model) throws Exception{
        System.out.println("#########" + code);
        
        /******************************************************
         *  카카오 리턴 값들~
         *****************************************************/
        String access_Token = "";
        if(code != null ) { 
        	access_Token = kakaoService.getAccessToken(code);
        }
        if(access_Token != "") { 
        	System.out.println("###access_Token#### : " + access_Token);
        	HashMap<String, Object> userInfo = kakaoService.getUserInfo(access_Token);
        	System.out.println("###access_Token#### : " + access_Token);
        	System.out.println("###userInfo#### : " + userInfo.get("email"));
        	System.out.println("###nickname#### : " + userInfo.get("nickname"));
        	System.out.println("###profile_image#### : " + userInfo.get("profile_image"));
        }
       
        return "home";
    }
}

 

service 

package com.me.genie.service;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;

import org.springframework.stereotype.Service;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

@Service
public class KakaoService {


        public String getAccessToken (String authorize_code) {
            String access_Token = "";
            String refresh_Token = "";
            String reqURL = "https://kauth.kakao.com/oauth/token";

            try {
            	/***************************************
            	 * 요청을 보낼 값 셋팅 
            	 **************************************/
            	 URL url = new URL(reqURL);
                 HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                 conn.setRequestMethod("POST");
                 conn.setDoOutput(true);// POST 요청을 위해 기본값이 false인 setDoOutput을 true로

                 
                 /***************************************
             	 * POST 요청에 필요로 요구하는 파라미터 스트림을 통해 전송 
             	 **************************************/
                 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream()));
                 StringBuilder sb = new StringBuilder();
                 sb.append("grant_type=authorization_code");
                 sb.append("&client_id=82693748acf2adcab6a974138e807eea");  // 발급받은 key
                 sb.append("&redirect_uri=http://localhost:8080/login");     // 설정해 놓은 경로
                 sb.append("&code=" + authorize_code);
                 bw.write(sb.toString());
                 bw.flush();

                 /***************************************
              	 * 결과 코드가 200이라면 성공 
              	 **************************************/
                 int responseCode = conn.getResponseCode();
                 System.out.println("responseCode : " + responseCode);


                 /***************************************
               	 * 결과 데이터 (JSON타입의 Response) 메세지 읽어오기 
               	 **************************************/
                 BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                 String line = "";
                 String result = "";
                 while ((line = br.readLine()) != null) {
                     result += line;
                 }

                 /***************************************
            	 * Gson 라이브러리에 포함된 클래스로 JSON파싱 객체 생성 
            	 **************************************/
                 JsonParser parser = new JsonParser();
                 JsonElement element = parser.parse(result);

                 /***************************************
             	 * 파싱된 데이터 읽어오기  
             	 **************************************/	
                 access_Token = element.getAsJsonObject().get("access_token").getAsString();
                 refresh_Token = element.getAsJsonObject().get("refresh_token").getAsString();

                 System.out.println("access_token : " + access_Token);
                 System.out.println("refresh_token : " + refresh_Token);

                 
                 /***************************************
              	 * 스트림은 사용 후 꼭 닫아주기! 
              	 **************************************/	
                 br.close();
                 bw.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            return access_Token;
        }
        
        
        public HashMap<String, Object> getUserInfo (String access_Token) {

        	 /***************************************
          	 * 사용자마다 정보가 다를 수 있기에 HashMap타입으로 선언 
          	 **************************************/	
            HashMap<String, Object> userInfo = new HashMap<String, Object>();
            String reqURL = "https://kapi.kakao.com/v2/user/me";
            try {
            	
            	/***************************************
              	 * 요청을 보낼 값 셋팅 
              	 **************************************/
                URL url = new URL(reqURL);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");

                /***************************************
              	 * 요청에 필요한 Header에 포함될 내용 
              	 **************************************/
                conn.setRequestProperty("Authorization", "Bearer " + access_Token);
                
                /***************************************
              	 *결과 코드가 200이라면 성공 
              	 **************************************/
                int responseCode = conn.getResponseCode();
                System.out.println("responseCode : " + responseCode);

                
                /***************************************
              	 *결과 데이터 (JSON타입의 Response) 메세지 읽어오기 
              	 **************************************/
                BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String line = "";
                String result = "";
                while ((line = br.readLine()) != null) {
                    result += line;
                }
                br.close();
                System.out.println("response body : " + result);

                
                /***************************************
            	 * Gson 라이브러리에 포함된 클래스로 JSON파싱 객체 생성 
            	 **************************************/
                JsonParser parser = new JsonParser();
                JsonElement element = parser.parse(result);
                
                
                /***************************************
             	 * 파싱된 데이터 읽어오기  
             	 **************************************/	
                JsonObject properties = element.getAsJsonObject().get("properties").getAsJsonObject();
                JsonObject kakao_account = element.getAsJsonObject().get("kakao_account").getAsJsonObject();

                String nickname = properties.getAsJsonObject().get("nickname").getAsString();
                String profile_image = properties.getAsJsonObject().get("profile_image").getAsString();
                String email = kakao_account.getAsJsonObject().get("email").getAsString();

                userInfo.put("nickname", nickname);
                userInfo.put("email", email);
                userInfo.put("profile_image", profile_image);
                
                
                
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
               
            }

            return userInfo;
        }
}

 

오늘은 카카오톡 연동 가이드를 작성해본다~ 

가이드로 사용할거라 시큐리티 없이 기능만 작성해둔다! 

시작!! 

 

1. 카카오톡 개발자 사이트 접속 후 계정 생성!  (developers.kakao.com/)

 

2. 로그인하면 나오는 화면인데 내 어플리케이션 메뉴에 들어가 어플리케이션을 추가한다! 

 

 

3. 플러스 모양 버튼이 나오면 아래와 같은 창이 뜬다. 내용 입력해주기~ 

 

 

4. 프로젝트를 생성하면  사용할 키들이 발급된다.

 

 

5. 카카오로그인 메뉴로 가서 리다이렉트 URL 을 설정해준다.

 

6. 사용자에게 받을 동의항목을 설정해준다. 사용자의 이메일을 받고 싶다면 아래의 이미지처럼 이메일도 추가해야한다.

이제 카카오톡은 이메일 없이도 회원가입이 가능해서 이점 유의하기! 

 

<이전포스팅>

 

[Google 로그인] #2 FRONT 코드작성!

지난 포스팅에서 로그인 기능을 사용할 준비를 했다면 이제 직접 구현해보자! < 지난 포스팅! > [Google 로그인] #1 개발자 콘솔 가입! 1. 구글 개발자 콘솔에 로그인한다. console.developers.google.com/ Googl

genie-dev.tistory.com

 

Spring maven 환경에서 사용할

가이드 용도로 작업한거라 간단하게 기능만 짤라서 구현한 내용임! 

(시큐리티 적용 X)

 

순서는 이렇다~ 

1. 로그인페이지에서 구글 로그인 

2. 결과로 리턴받은 토큰을 서버로 전송 

3. 토큰을 이용해서 서버단에서 다시한번 사용자 정보 요청 

4. 프론트에서 넘어온 정보와 서버단에서 가져온 사용자 정보가 일치하는지 확인

5. 로그인 처리 or 내가 원하는 다른 작업을 진행하면 된다. 

 

pom.xml ( 필요한 기능들을 추가해준다. ) 

		<!--  새로 추가  -->
		<dependency>
		    <groupId>com.fasterxml.jackson.core</groupId>
		    <artifactId>jackson-core</artifactId>
		    <version>2.12.1</version>
		</dependency>
		
		<dependency>
		    <groupId>com.fasterxml.jackson.core</groupId>
		    <artifactId>jackson-databind</artifactId>
		    <version>2.12.1</version>
		</dependency>
		
		<dependency>
		    <groupId>com.fasterxml.jackson.core</groupId>
		    <artifactId>jackson-annotations</artifactId>
		    <version>2.12.1</version>
		</dependency>
		
		<dependency>
		    <groupId>org.codehaus.jackson</groupId>
		    <artifactId>jackson-mapper-asl</artifactId>
		    <version>1.9.13</version>
		</dependency>
				
		
		<dependency>
		    <groupId>com.google.code.gson</groupId>
		    <artifactId>gson</artifactId>
		    <version>2.8.6</version>
		</dependency>
		
		<dependency>
	     <groupId>com.google.api-client</groupId>
	     <artifactId>google-api-client</artifactId>
	     <version>1.31.2</version>
	   </dependency>
	   
		<dependency>
		    <groupId>com.google.api-client</groupId>
		    <artifactId>google-api-client-jackson2</artifactId>
		    <version>1.20.0</version>
		</dependency>
	  

 

VO 생성 ( 내가 받을 내용을 작성하면 되는데 테스트용이므로 간단하게 작성했다.)

public class UserVO {
	private String email;
	private String token;
	
	public String getToken() {
		return token;
	}

	public void setToken(String token) {
		this.token = token;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	} 
	
}

 

Controller 생성 ( 요청을 받을 컨트롤러를 작성한다)

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;


import com.me.genie.service.GoogleService;
import com.me.genie.vo.UserVO;

import java.io.IOException;

@Controller
public class GoogleController {
	
	@Autowired GoogleService googleService;
	
	/**
	 * Authentication Code를 전달 받는 엔드포인트
     * 구글 개발자 사이트에서 리턴url로 적었을 경우만 가져옴
     * 백엔드에서 받는 방법도 보여주고자 작성함
	 * @throws IOException 
	 * @throws JsonProcessingException
	 * @throws JsonMappingException
	 **/
	@RequestMapping(value = "/google/auth")
	public String googleAuth(Model model, @RequestParam(value = "code") String authCode) throws IOException{
		// 구글이 리턴해준 코드가 들어온다.
		System.out.println("AUtho code : " + authCode);
		googleService.getToken(authCode);
		return "/home";
	}
	
	
	/**
	 * 프론트로부터 ajax 요청을 받는다.
	 * @param user
	 * @return
	 */
	@RequestMapping(value = "/google/userinfo", produces = "application/json")
	@ResponseBody 
	public Map<String, Object> revokeToken(UserVO user) {
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("res", googleService.tokenCheck(user));
		return result;

	}

}

 

Service ( 비즈니스 로직처리할 서비스 구현)

import com.google.gson.JsonElement;
import com.google.gson.JsonParser;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collections;

import org.springframework.stereotype.Service;


import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;

import com.me.genie.service.GoogleService;
import com.me.genie.vo.UserVO;

@Service
public class GoogleService {
	final static String GOOGLE_AUTH_BASE_URL = "https://accounts.google.com/o/oauth2/v2/auth";
	final static String GOOGLE_TOKEN_BASE_URL = "https://oauth2.googleapis.com/token";
	final static String GOOGLE_REVOKE_TOKEN_BASE_URL = "https://oauth2.googleapis.com/revoke";
	final static String GOOGLE_GET_USER_INFO_URL = "https://www.googleapis.com/oauth2/v1/userinfo?access_token=";
	final static String clientId = "나의 클라이언트키";
	final static String clientSecret = "비밀키";
	
	 private static final HttpTransport transport = new NetHttpTransport();
	 private static final JsonFactory jsonFactory = new JacksonFactory();
	
	 /**
	 * 백엔드단에서 토큰을 얻어온다.
	  * @param authCode
	  * @return access_Token
	  * @throws IOException
	  */
	public String getToken(String authCode) throws IOException {
		
		/**************************************
         * Access 토큰을 가져오기 위한 설정
         *************************************/
		URL url = new URL(GOOGLE_TOKEN_BASE_URL);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setDoOutput(true);

        
        /**************************************
         * 파라메터 설정
         *************************************/
        StringBuffer sbf = new StringBuffer();
        sbf.append("code=");sbf.append(authCode);
        sbf.append("&client_id=");sbf.append(clientId);
        sbf.append("&client_secret=");sbf.append(clientSecret);
        sbf.append("&redirect_uri=");sbf.append("http://localhost:8080/google/auth");
        sbf.append("&grant_type=");sbf.append("authorization_code");
        String  parameterString = sbf.toString();
		
        
        /**************************************
         * 요청을 보내고 받을 스트림 생성
         *************************************/
		BufferedOutputStream bous = new BufferedOutputStream(conn.getOutputStream());
		bous.write(parameterString.getBytes()); 
		bous.flush(); 
		bous.close();
		
		BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
		
		/**************************************
         * 받아온 데이터를 sb에 저장
         *************************************/
		StringBuilder sb = new StringBuilder(); 
		String line;
		while ((line = br.readLine()) != null) { 
			sb.append(line); 
		}
		
		/**************************************
         * 받아온 데이터에서 토큰 추출
         *************************************/
		String access_Token ="";
		if (conn.getResponseCode() == 200) { 
            JsonParser parser = new JsonParser();
            JsonElement element = parser.parse(sb.toString());
            access_Token = element.getAsJsonObject().get("access_token").getAsString();
            System.out.println("access_token : " + access_Token);
            
            if(access_Token!=null) {
                /***사용자 정보 요청 **/
            	userinfo(access_Token);
            }
		}
		return access_Token;
	}
	
	/**
	 * access_token 이용하여 사용자 정보를 가져온다.
	 * @param access_token
	 */
	public void userinfo(String access_token) {
		try { 
			
			/**************************************
	         * 사용자 정보를 가져오기 위한 셋팅
	         *************************************/
	        URL url = new URL(GOOGLE_GET_USER_INFO_URL+access_token);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET"); 
			conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			conn.setDoOutput(true);
			
			
			/**************************************
	         * 요청을 보내고 받을 스트림 생성
	         *************************************/
			BufferedOutputStream bous = new BufferedOutputStream(conn.getOutputStream());
			bous.flush(); 
			bous.close();
			
			BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			StringBuilder sb = new StringBuilder(); String line;
	  
			while ((line = br.readLine()) != null) { 
				sb.append(line); 
			}
			 
			/**************************************
	         * 받아온 데이터에서 출력
	         *************************************/
			if (conn.getResponseCode() == 200) { 
				System.out.println(sb.toString()); 
			}
			
		} catch (Exception e) {
			System.out.println("ERROR. . . PLEASE CHECK ... [GoogleService.userinfo]");
			e.printStackTrace();
		}
	}
	
	/**
	 * 사용자단에서 가져온 토큰값으로 
	 * 유효한사용자인지, 요청온 이메일은 맞는지 확인한다.
	 * @param user
	 * @return 유효여부
	 */
	public boolean tokenCheck(UserVO user) {
		boolean res = false;
		try {
			
			/**************************************
	         * 사용자 정보를 가져오기 위해 구글에서 
	         * 제공하는 설정 셋팅
	         *************************************/
			GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
			    .setAudience(Collections.singletonList(clientId))
			    .build();
		
			/**************************************
	         * 프론트 단에서 로그인 후 받아온 코드 설정 후 
	         * 사용자 정보를 가져온다.
	         *************************************/
			GoogleIdToken idToken = verifier.verify(user.getToken());
			
			// 사용자 정보가 존재하는지 확인
			if (idToken != null) {
			  // 사용자 정보가 담긴 데이터를 가져온다.
			  Payload payload = idToken.getPayload();
		
			  // 사용자 고유 ID 가져온다.
			  String userId = payload.getSubject();
			  System.out.println("User ID: " + userId);
		
			  // 그외 사용자 정보를 가져온다.
			  String email = payload.getEmail();
			  String name = (String) payload.get("name");
			  String pictureUrl = (String) payload.get("picture");
			  String locale = (String) payload.get("locale");
			  String familyName = (String) payload.get("family_name");
			  String givenName = (String) payload.get("given_name");
			  
			  /**************************************
	          * 프론트 단에서 로그인을 시도한 이메일과, 코드를 통해 가져온 정보가 일치하는지 확인한다. 
	          *************************************/
			  if(user.getEmail().equals(email)) { 
				  res = true; 
			  }
			  
			} else {
			  System.out.println("Invalid ID token.");
			}
			
		} catch (Exception e) {
			System.out.println("ERROR. . . PLEASE CHECK ... [GoogleService.userinfo]");
			e.printStackTrace();
		}
		return res;
	}
}

 

home.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
	<title>Home</title>
	<script src="https://apis.google.com/js/platform.js" async defer></script>
	<meta name="google-signin-client_id" content="{발급받인 클라이언트 아이디}.apps.googleusercontent.com"></meta>
</head>
<body>

  
    <h1>로그인</h1>
    <hr>

    <form action="/user/login" method="post">
        <input type="text" name="username" placeholder="이메일 입력해주세요">
        <input type="password" name="password" placeholder="비밀번호">
        <button type="submit">로그인</button>
        
        <!-- 구글 로그인  -->
		<div class="g-signin2" data-onsuccess="onSignIn"></div>
		<!-- 구글 아웃 -->
		<a href="#" onclick="signOut()">구글 로그아웃</a>
        
        
  		
    </form>
	
    
    <script src="/resources/css/bower_components/jquery/dist/jquery.min.js"></script>
	<script src="/resources/css/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
	<script src="/resources/css/dist/js/adminlte.min.js"></script>
	<script src="/resources/js/utils/easy_ui/jquery.easyui.min.js"></script>
    <script>
	function onSignIn(googleUser) { 
		
    	var profile = googleUser.getBasicProfile(); 
		/*
    	console.log('ID: ' + profile.getId()); // 이건 백엔드로 보내면 안됨! 보안의 위험이 있음. 
    	console.log('Name: ' + profile.getName()); 
    	console.log('Image URL: ' + profile.getImageUrl()); 
    	console.log('Email: ' + profile.getEmail()); // This is null if the 'email' scope is not present.
		console.log(googleUser.getAuthResponse().id_token); // 서버에 던질땐 보안을 위해 이값으로 던져준다.
		*/
		
		var email = profile.getEmail();
		var token = googleUser.getAuthResponse().id_token;
    	$.ajax({
    	    url:'/google/userinfo', 
    	    type:'post', 
    	    data:{'token': token, 'email': email}, 
    	    success: function(data) {
    	        if(data.res) { 
	    	        alert("OK");
       	        } else {
       	        	alert("비정상로그인 접근입니다.");
           	    }
    	    },
    	    error: function(err) {
    	        //서버로부터 응답이 정상적으로 처리되지 못햇을 때 실행
    	    }
    	});
    }
	 
	function signOut() { 
    	var auth2 = gapi.auth2.getAuthInstance(); 
    	auth2.signOut().then(function () {
        	 self.location="로그아웃할 url"; 
        }); 
   	 } 
  	</script>

   
</body>
</html>


 

 

SQL Injection 에 대한 조치를 진행해본다. 

 

예를 들면 검색 기능을 구현한다고 보면 간단하게 아래와 같은 쿼리를 작성하게 된다. 

SELECT * FROM MYTABLE WHERE NAME LIKE '% ?'; 

 

만약 악의적인 사용자가 파라메터값으로 " '; SHOW DATABASES; -- " 이런 구문을 입력해 온다면 

SELECT * FROM MYTABLE WHERE NAME LIKE '%'; SHOW DATABASE; -- '; 

나의 쿼리 문은 종료되고, 뒤엔 데이터베이스를 출력할 수 있는 쿼리가 실행되게 된다. 

만약 공격자가 테이블을 조회하는 쿼리를 넣었다면 테이블명까지 노출되고 

심할경우 drop을 통해 테이블이 삭제되는 경우에 이를 수 있다. 

이렇게 입력값을 이용해 내 쿼리를 조회를 방해하고, 악의적으로 데이터를 갈취할수 있는데 

이에 방어하기 위한 조치를 진행해본다. 

 

1. Codeigniter 에서 제공하는 xss_clean 사용! 

xss_clean크로스 사이트 스크립팅 공격을 방지하는 XSS 필터는 자바스크립트실행을 시도한다거나, 쿠키를 하이재킹한다거나, 다른 해괴망측한 짓거리들을 한다거나 하는 것을 막는 기술입니다. 만약 금지된 문자나 코드 등을 찾으면 데이터를 안전한 HTML 엔터티로 변환하여 표시합니다.

컨트롤러에서 검색값을 받을때 아래와 같이 필터링해준다. 

$search["keyword"] = $this->security->xss_clean(@trim($search["keyword"]));

 

2. 정규식을 이용한 문자열 치환 

파라메터값에서 쿼리 조회에 문제가 되는 텍스트가 있다면 "" 으로 변경해준다. 

$string = @trim(preg_replace("/[#\&\+\-%@=\/\\\:;,\.'\"\^`~\_|\!\?\*$#<>()\[\]\{\}]/i", "", $string));

 

3. 한번 더 문자열 치환! 

이건 경우에 따라 다를 것 같다.  나같은 경우 들어올 사용자 이름 조회에 사용하고있으므로

파라메터에 select 와 같은 문구가 들어올 경우가 적기에 이 또한 "" 처리했는데, 

케바케로 용도에 맞게 사용해야할것같다. (str_ireplace = 이건 대소문자 구분없이 문자열 변경해준다. ) 

//iframe 제거 
$string = preg_replace("!<iframe(.*?)<\/iframe>!is","",$string);

//script 제거 
$string = preg_replace("!<script(.*?)<\/script>!is","",$string);

//meta 제거 
$string = preg_replace("!<meta(.*?)>!is","",$string); 

//style 태그 제거  
$string = preg_replace("!<style(.*?)<\/style>!is","",$string); 

// 기타 쿼리 조회에 사용되는 문구 제거 
$string = @trim(str_ireplace("select", "", $string));
$string = @trim(str_ireplace("union", "", $string));
$string = @trim(str_ireplace("insert", "", $string));
$string = @trim(str_ireplace("update", "", $string));
$string = @trim(str_ireplace("delete", "", $string));
$string = @trim(str_ireplace("drop", "", $string));
$string = @trim(str_ireplace("from", "", $string));

 

4. 한번 더 걸러준다.. ( 절대 안되게 할꺼야! )ㅋㅋ

날짜와 같이 스크립트로 값을 입력해 가져오는 파라메터들에 방심하는 경우가 있다. 

공격툴을 이용하면 파라메터 값을 마음대로 셋팅할 수 있으므로,  입력받는 파라메터라면 모두 처리해주어야한다. 

$search["keyword"] = addslashes($search["keyword"]);
$search["sdate"] = addslashes($search["sdate"]);
$search["edate"] = addslashes($search["edate"]);

 

 

쿼리 실행 코드 뒤에 아래 코드를 입력하면 화면에 

찍힌다~!! 

$last_query = $this->db->last_query();
echo $last_query;

 

'PHP' 카테고리의 다른 글

Codeigniter Hooks 사용방법!  (0) 2021.01.28

+ Recent posts