coding

PRG 패턴 (Post-Redirect-Get) Post 중복처리 문제 해결 패턴

사과키라임파이 2022. 3. 11. 16:46

브라우저에서 새로고침이나 뒤로 가기를 했을 경우 이전에 보내진 POST 요청이 다시 보내져 중복 결제가 일어나는 버그

 

https://programmer93.tistory.com/76

 

PRG 패턴 (Post-Redirect-Get) - 삽질중인 개발자

최근 발생한 이슈 중 중복 결제에 대한 이슈가 있어서 원인을 찾아보는 중에 브라우저에서 새로고침이나 뒤로 가기를 했을 경우 이전에 보내진 POST 요청이 다시 보내져 중복 결제가 일어나는 버

programmer93.tistory.com

 

 

 

 

https://ynzu-dev.tistory.com/entry/Web-PRG-%ED%8C%A8%ED%84%B4-Post-Redirect-Get

 

 

[Web] PRG 패턴 (Post - Redirect - Get)

PRG 패턴이란? Post -> Redirect -> Get 패턴으로 만들어지는 것을 말하며, 권장되는 디자인 패턴 중 하나다. PRG 패턴의 필요성 예를 들어 상품 판매 서비스를 운영하고 있다고 하자. 주문 페이지를 호출

ynzu-dev.tistory.com

 

 

PRG(Post-Redicet-Get)패턴은 웹 개발시 사용 권장되는 디자인 패턴입니다. 

사용자의 뒤로가기, 새로고침으로 인한 중복입력을 방지할 수 있습니다.

EX) 상품주문

 

PRG패턴 적용 전


상품 주문 흐름도

사용자가 상품 주문 후 주문완료 페이지에서 새로고침을 수행한다면 

마지막 요청인 POST 주문입력 요청이 수행되게됩니다. 

이럴경우 사용자가 새로고침을 수행할 때 마다 DB에 입력되어 문제를 야기할 수 있습니다.

 

PRG패턴 적용


PRG패턴 흐름도

최초 상품주문 후 서버에서 주문조회 페이지에 대한 Redirect수행합니다.

이럴 경우 사용자가 주문완료 페이지에서 새로고침을 하더라도 마지막요청이 

상품조회 GET요청이기 때문에 주문이 아닌 주문조회 로직이 수행되게 됩니다. 

 

https://juinor.tistory.com/m/32

[Web] PRG 패턴 (Post - Redirect - Get)

 

 

PRG 패턴이란?

Post -> Redirect -> Get 패턴으로 만들어지는 것을 말하며, 권장되는 디자인 패턴 중 하나다.

 

PRG(Post-Redicet-Get)패턴은 웹 개발시 사용 권장되는 디자인 패턴입니다. 

사용자의 뒤로가기, 새로고침으로 인한 중복입력을 방지할 수 있습니다.

EX) 상품주문

 

PRG 패턴의 필요성

예를 들어 상품 판매 서비스를 운영하고 있다고 하자. 

주문 페이지를 호출하고, Post 방식으로 결제를 처리할 경우 결제 완료 페이지에서 실수 혹은 의도적으로 새로고침을 하게 되면 서버에 전송했던 데이터를 다시 전송하게 되어 중복 결제 처리가 될 수 있다.

자세한 프로세스는 아래 포스팅을 참고하자

 

[WEB] PRG패턴

PRG(Post-Redicet-Get)패턴은 웹 개발시 사용 권장되는 디자인 패턴입니다. 사용자의 뒤로가기, 새로고침으로 인한 중복입력을 방지할 수 있습니다. EX) 상품주문 PRG패턴 적용 전 사용자가 상품 주문

juinor.tistory.com

 

PRG 패턴을 사용하지 않으면 위와 같은 새로고침으로 인한 중복 요청 이슈도 있고, 요청 결과에 해당하는 페이지를 공유하는 것이 어려워진다는 문제점이 있다. 기본적으로 사용자는 URL만 가지고는 GET 방식의 요청 밖에 할 수 없어 POST 방식의 URL은 공유하더라도 다른 페이지로 이동하는 결과가 나타난다.

 

간단하게 PRG 패턴 적용 전, 후의소스를 비교해보자.

 

PRG 패턴 적용 전 소스

@Controller
class TestController {

    @GetMapping("/order")
    public String order(){
		//주문 페이지 호출
        return "order";
    }

    @PostMapping("/buy")
    public String buy(){
        // 결제 처리
        return "result message"; //결제 처리 결과를 리턴
    }
}

PRG 패턴 적용 전 소스
사용자가 결제를 하게 되면 'xxx.com/buy' 라는 url이 호출되며, 결제 프로세스가 진행되고, 결제 처리 결과가 리턴된다.
하지만 url은 'xxx.com/buy'로 동일하게 남아 있기 때문에 새로고침했을 경우 다시 결제 요청이 되며 중복 결제가 발생한다.

 

 

 

PRG 패턴 적용 후 소스

@Controller
class TestController {

    @GetMapping("/order")
    public String order(){
		//주문 페이지 호출
		return "order";
    }

    @PostMapping("/buy")
    public String buy(){
		// 결제 처리
		return "redirect:/buy-result";
		
    }

    @GetMapping("/buy-result")
    public String buyResult(){
		//결제 결과 페이지 호출
		return "buyResult";
    }
}