입력된 URL 값이 특정 도메인지를 정규식으로 확인하는 방법입니다.

만약, 사용자에게 URL 값을 입력받아야 하는 경우 잘못된 URL 이나 악의적인 URL이 입력될 가능성이 있습니다.

이런 경우를 방지하기 위해 몇가지의 도메인들만 허용하도록 해야하는 경우 정규식을 활용한 방법을 알아보겠습니다.

정규식 코드 ( PHP )

$url = "https://yoursite.hacking.com";
$regex = "/^(https?:\/\/)([^\/]*)(\.)(tistory\.com|naver\.com|blog\.me)(\/)(.*)/i";
if (!preg_match($regex, $url)) {
    alert('올바른 블로그 URL이 아닙니다. URL을 확인해주세요.');
    exit;
}

위 예시는 특정 블로그(티스토리,네이버)의 글의 URL만 허용하고 싶은 경우를 가정하였고,
티스토리와 네이버 블로그 URL 형식은 대략적으로 아래와 같습니다.

티스토리/네이버 블로그 URL 형식 예시
https://blogid.tistory.com/게시글번호
https://blog.naver.com/blogid/게시글번호
http://blogid.blog.me/게시글번호

위와 같은 URL들은 https://{가변적인 값}.site.com/ 처럼 가변적인 값(블로그마다 다른 값)이 중간에 사용되는 특성이 있습니다.

고정된 URL이라면 정규식을 사용할 필요가 없을테지만

바로 저 가변적인 값이 있기 때문에 정규식으로 2차 도메인의 값 (tistory.com, naver.com, blog.me)의 패턴을 체크합니다.

( 물론 정규식을 사용하지않고도 할 수는 있습니다만.. 더 비효율적이고 복잡하므로…. )

그냥 그대로 사용하셔도 무관하지만 좀 더 이해해보고싶다하시는 분들을 위해 정규식을 하나하나 뜯어서 분석해보시죠.

괄호 단위로 분석해보겠습니다.
다만 괄호로 묶은것은 제가 볼때 편하게 보기 위해서입니다.

원래 괄호도 정규식에서의 별도의 역할이 있으니 괄호 사용시 주의가 필요합니다.

1. ^(https?:\/\/)

https:// or http:// 로 시작하는 URL 인 경우라는 뜻입니다.

^ 는 문자열의 시작을 나타내며, https? 는 ? 앞에 1글자(s)가 있을 수도 있고 없을 수도 있다

= http 일수도 있고 https 일 수도 있다라는 것

그뒤에는 :// 문자열 그대로 입니다.
( 다만 / 기호는 정규식에서 특별한 의미로 쓰이는 기호이기 때문에 역슬래쉬(\) 로 escape 해줘서 문자로 인식하도록 하였습니다. )

그러므로 결과적으로 “문자열의 시작이 http:// or https:// 로 시작하는~” 이 됩니다.

2. ([^\/]*)

이 부분은 원하지 않는 글자가 특정 부분에 포함되면 안되도록 처리하기 위한 방법입니다.

예를들어
[^(\/)]* 는  슬래쉬(/) 문자가 중간에 포함되지 않아야한다 라는 뜻
[^(abc)]* 는 a,b,c 문자가 중간에 포함되지 않아야한다 라는 뜻
[^(0-9)]* 는 0-9 문자들(숫자들)이 중간에 포함되지 않아야한다 라는 뜻

해당 정규식을 기준으로는 다음 3번의 (\.) 문자가 나오기 전에 해당 문자들이 나오면 안된다가 됩니다.

해당 부분을 왜 사용했냐면 이부분을 사용하기전에는 (.*) 로 했었는데,

아래와 같은 변칙적인 URL 들을 입력했을때  올바른 URL로 처리가되서 이부분을 방지하기 위해 변경하였습니다.

변칙적인 URL

https://yoursite.hacking.com/blog.naver.com/111

([^\/]*) 와 (.*) 를 사용하는 두가지 경우로 테스트해보시면 아실 수 있을겁니다.

*추가

이글을 쓰다보니 블로그의 3차 도메인 부분의 패턴은 다 문자열이다보니 ([^\/]*) 부분을 아래와 같이 바꿔도 됩니다.

([a-zA-z]*) :영어 대소문자만 포함가능.

기존은 포함하면 안되는 문자열을 정의하는 방식이라면

이건 해당 문자열들만 포함되어야한다는 방식이므로 이게 더 쉽고 확실하네요. ^^;;

3. (\.)

이부분은 3차도메인 형식을 체크하기 위함입니다.

2차도메인은 https://tistory.com 과 같이 https:// 다음에 .이 안나오고 바로 도메인이 나오지만

3차도메인은 https://blogid.tistory.com 과 같이 https:// 다음에 3차도메인이나오고 . 이 나오기 때문입니다.

그러므로 https:// 와 2차도메인(tistory.com) 이 시작되기전에 . 있는지를 체크하는것입니다.

그리고 ( . ) 기호는 정규식에서 특별한 의미로 사용되는 기호이므로 문자로 인식하도록 escape 처리해주었습니다.

4. (tistory\.com|naver\.com|blog\.me)

2차도메인의 주소들입니다. 
( 3차도메인을 이미 체크한 상태이므로 꼭 2차도메인 부분만 적어주셔야하는점을 주의하세요. )

도메인을 추가하려면 파이프(|) 기호로 구분해서 추가해주시면 됩니다.

5. (\/)

블로그 URL의 경우 https://aaa.tistory.com 으로만 끝나지 않고 https://aaa.tistory.com/123 처럼 뒤에 게시글 번호가 붙습니다. 

이처럼 URL 뒤에 / 가 붙어야 하는 경우를 위해 추가 되었습니다.

그러므로 https://aaa.tistory.com 처럼 입력하면 잘못된 URL로 체크가 됩니다.

/ 를 붙이지 않은 URL로 체크하고 싶다면 (\/) 부분을 빼버리면 됩니다.

6. (.*)

모든 문자열을 허용함이라는 뜻입니다.

이미 5번까지 도메인 체크를 정상적으로 마쳤으므로 이 이후는 아무 문자열이나 와도 상관없게되는거죠.

이상으로 특정 3차 도메인들의 패턴을 체크하는 방법들을 알아보았습니다.

마지막으로 정규식을 테스트해볼 수 있는 사이트 하나 남겨놓고 사라지겠습니다~ 뿅!

https://regexr.com/56j44

( 위 URL로 접속하시면 정규식과 예제를 몇개 입력해두었고 추가로 원하는 URL 들을 입력해보고 테스트 및 정규식 개선/수정도 가능합니다. )

감사합니다. 😄