코딩하는 오징어

Redirect 와 Forward 본문

알쓸신잡

Redirect 와 Forward

코딩하는 오징어 2020. 4. 27. 00:18
반응형

오늘은 가벼운 주제를 다뤄보겠습니다. Redirect와 Forward의 개념과 둘의 차이를 정리하려고합니다. 어렵지 않은 개념이지만 확실하게 정리를 해두지 않으면 자주 혼동하거나 다시 검색하게 되는 개념입니다.

Redirect

Redirect는 Wiki에 다음과 같이 정리되어있습니다.

A redirect is a page which automatically sends visitors to another page, usually an article or section of an article.

Redirect는 방문자를 다른 페이지로 자동으로 보내주는 페이지이다. 그림으로 Redirect의 동작 방식을 표현한다면 다음과 같을 것 입니다.

redirect

사용자는 어떤 페이지를 서버에 요청하게되고 서버는 다른 페이지의 url을 Location 헤더에 담아 http status code를 3xx로 설정하여 응답을 줄 것입니다. 그럼 클라이언트는 응답받은 정보를 토대로 다른 url로 다시 요청하게 되는 것 입니다. url의 호스트는 같을 수도 있고 다를 수도 있습니다. 서버의 재량인 것이죠. 그럼 Redirect는 어떨 때 사용 될까요?? 여러 상황에서 사용되겠지만 제가 아는 지식을 바탕으로 다음과 같은 두 가지 예를 소개하려합니다.

  1. 클라이언트가 요청한 페이지 혹은 리소스가 기존의 장소(url)가 아닌 다른 곳으로 옮겨 졌을 때 해당 리소스로 안내를 하는 것 입니다. 휴대전화를 바꾸면서 번호도 같이 바뀌게 된경우 기존 번호로 전화를 하게 되면 새로운 번호를 알려주는 서비스를 생각해보시면 될 것 입니다.
  2. OAuth2.0 Spec을 보시면 인증을 제공하는 여러가지 방법 중 대표적으로 Authorization Code Grant 방식이 있습니다. Authorization Code Grant 방식은 사용자의 로그인이 완료되면 Protected Resource에 접근 할 수 있는 AccessToken을 발급 받을 수 있는 code를 기존에 설정해둔 Redirect URL의 query parameter로 전달합니다. query paramter로 전달 받은 code를 이용하여 Access Token을 발급 받을 수 있게 됩니다.

Spring Web MVC를 이용하여 실제 동작을 살펴봅시다. 예제 코드는 다음과 같습니다.

@RestController
@RequiredArgsConstructor
public class RedirectController {

    @GetMapping("/redirect/origin")
    public ResponseEntity<Object> redirect() throws URISyntaxException {
        URI redirectUri = new URI("http://localhost:8090/redirect/target?code=" + UUID.randomUUID());
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setLocation(redirectUri);
        return new ResponseEntity<>(httpHeaders, HttpStatus.FOUND);
    }

    @GetMapping("/redirect/target")
    public String target(@RequestParam("code") long code) {
        System.out.println(">>> " + code);
        return "redirect param :" + code;
    }
}

curl을 통하여 요청 해보면 위와 같은 결과를 얻을 수 있습니다. (--location 옵션을 주지않으면 redirect action을 취하지 않습니다.)  9 ~ 10번 째 줄이 처음 요청에 대한  응답 상태코드 302와 함께 Location 헤더에 redirect할 query paramter가 포함된 url을 넘겨주게됩니다. 클라이언트는 이 정보를 가지고 다시 GET요청을 하게 되는 것 입니다. 브라우저를 통해 요청한 결과는 다음과 같습니다.

브라우저를 통해 실행한 결과를 잘 살펴보아야합니다. http://localhost:8090/redirect/origin으로 요청을 하였는데, 결과창에 url이 http://localhost:8090/redirect/target?code=e90c9f15-cb53-44d7-9c7f-17b2c2060bd3로 바뀐 것을 확인할 수 있습니다. forward와의 결정적인 차이임으로 기억해두길 바랍니다.

Forward

forward는 redirect와 비슷하지만 조금은 다른 개념입니다. redirect를 휴대전화를 바꾸면서 번호도 같이 바뀌게 된 경우 기존 번호로 전화를 하게 되면 새로운 번호를 알려주는 서비스에 비유한다면 forward는 휴대전화를 바꾸면서 번호도 같이 바뀌게 된 경우 기존 번호로 전화를 하게 되면 새로운 번호로 연결 시켜주는 서비스에 비유할 수 있습니다. 어떤 차이인지 보이시나요? redirect는 클라이언트가 안내받은 정보로 다시 요청을 보내는 액션을 취해야하지만 forward는 요청이후 새로운 액션을 취할 필요가 없습니다. 따라서 새로운 정보를 알수도 없게됩니다. 다음 그림과 예제 코드로 forward의 동작을 살펴봅시다.

forward

@RestController
@RequiredArgsConstructor
public class ForwardController {

    @GetMapping("/forward/origin")
    public String forward() throws URISyntaxException {
        URI forwardUri = new URI("https://www.daum.net");
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.getForObject(forwardUri, String.class);
    }
}

위의 코드를 보시면 /forward/origin으로 요청하면 www.daum.net으로 요청하여 받은 응답 값을 그대로 클라이언트에게 내려주고 있습니다. 결과는 다음과 같습니다.

redirect와 차이가 보이시나요?? forward는 요청한 url이 변하지 않습니다. redirect와 forward의 차이를 정리하면 다음과 같습니다.

  Redirect Forward
클라이언트의 추가 Action O X
URL 변화 O X

 

반응형
Comments