0

I have a spring boot app, which uses Pinterest api. In order to exchange the auth code for the token, I need to send a post request like this one

curl -c -v -X POST 'https://api.pinterest.com/v5/oauth/token' \
--header 'Authorization: Basic ...' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'code=...' \
--data-urlencode 'redirect_uri=https://localhost:8443/auth/pinterest'

and it works with curl, I get the response with the token and all is good.

However, when I am trying to do the same request in my app, I have a problem.

At first, I was receieving 302, making a request using the following

private val authTemplate = RestTemplateBuilder().rootUri("https://www.pinterest.com/")
        .setConnectTimeout(Duration.ofSeconds(6))
        .setReadTimeout(Duration.ofSeconds(6))
        .build()

fun exchangeCodeForToken(
        code: String,
        redirectUri: String,
        clientId: String,
        clientSecret: String,
    ): ResponseEntity<String> {
        val formMap = LinkedMultiValueMap<String, Any?>()
        linkedMapOf("grant_type" to "authorization_code", "code" to code, "redirect_uri" to redirectUri).forEach {
            formMap.add(it.key, it.value)
        }
        val authHeader = Base64.encode("""$clientId:$clientSecret""").toString()
        val headers = HttpHeaders().apply {
            this.setBasicAuth(authHeader)
            this.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
        }


        val requestEntity = HttpEntity(formMap, headers)
        val response = authTemplate.postForEntity(
            "/v5/oauth/token",
            requestEntity,
            String::class.java
        )

        return response
    }

So this one result into a 302 error. I tried googloing it and found out, that I can fix the issue, by assigning a factory to my rest template

    private fun getFactory(): HttpComponentsClientHttpRequestFactory {
        val factory = HttpComponentsClientHttpRequestFactory()
        val client = HttpClientBuilder.create().setRedirectStrategy(LaxRedirectStrategy())
            .build()
        factory.httpClient = client
        return factory
    }

...
        authTemplate.requestFactory = getFactory()

...

And it did fix the issue I had, there was no more a 302 in response. However, there was a response containing a page to log into pinterest.

The logs are as follows:

2022-05-02 20:23:13.490 DEBUG 13437 --- [nio-8443-exec-9] o.s.w.c.RestTemplate                     : HTTP POST https://www.pinterest.com/oauth/token
2022-05-02 20:23:13.492 DEBUG 13437 --- [nio-8443-exec-9] o.s.w.c.RestTemplate                     : Accept=[text/plain, application/json, application/*+json, */*]
2022-05-02 20:23:13.496 DEBUG 13437 --- [nio-8443-exec-9] o.s.w.c.RestTemplate                     : Writing [{grant_type=[authorization_code], code=[0769ee95e32c8ad10a6239cf42ecce1a03d65a58], redirect_uri=[https://localhost:8443/auth/pinterest]}] as "application/x-www-form-urlencoded"
2022-05-02 20:23:20.415  WARN 13437 --- [nio-8443-exec-9] o.a.h.c.p.ResponseProcessCookies         : Invalid cookie header: "Set-Cookie: csrftoken=d3d9dd63d0d296c84f2d41ec18df02d6; path=/; expires=Tue, 02 May 2023 21:23:30 GMT; samesite=lax; secure". Invalid 'expires' attribute: Tue, 02 May 2023 21:23:30 GMT
2022-05-02 20:23:20.416  WARN 13437 --- [nio-8443-exec-9] o.a.h.c.p.ResponseProcessCookies         : Invalid cookie header: "Set-Cookie: _pinterest_sess=TWc9PSZmRC9UeUpDM2VrZ3JyU3FDVXUxU1RpZkNYQkNYVWxGaE4yb2orMFQwSXp1SzkrRG13TGhHTm9oWFVXVS9ncnNEdjBSNU5DaTNHQzk0OW5Lb2IrV1YvSlpGS2g0MWxpMEppNFdBTStHU1ltcz0mWEViWXpocDJzNm1QUGdWbnhrdlBhaG1venhnPQ==; path=/; expires=Thu, 27 Apr 2023 21:23:30 GMT; domain=.pinterest.com; samesite=none; secure; httponly". Invalid 'expires' attribute: Thu, 27 Apr 2023 21:23:30 GMT
2022-05-02 20:23:20.418  WARN 13437 --- [nio-8443-exec-9] o.a.h.c.p.ResponseProcessCookies         : Invalid cookie header: "Set-Cookie: _auth=0; path=/; expires=Thu, 27 Apr 2023 21:23:30 GMT; domain=.pinterest.com; secure; httponly". Invalid 'expires' attribute: Thu, 27 Apr 2023 21:23:30 GMT
2022-05-02 20:23:20.420 DEBUG 13437 --- [nio-8443-exec-9] o.s.w.c.RestTemplate                     : Response 200 OK
2022-05-02 20:23:20.424 DEBUG 13437 --- [nio-8443-exec-9] o.s.w.c.RestTemplate                     : Reading to [java.lang.String] as "text/html;charset=utf-8"
2022-05-02 20:23:20.627 DEBUG 13437 --- [nio-8443-exec-9] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Found 'Content-Type:text/html;charset=utf-8' in response
2022-05-02 20:23:20.629 DEBUG 13437 --- [nio-8443-exec-9] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Writing ["<!DOCTYPE html><html class="en" lang="en">

Now I really do not understand what is going on. I found another answer on a similar issue, suggesting I should disable cookie manager for my client and I did, but it did not help.

What is so different about it, that it doesn't work the way that curl does? If not possible possible to make this request correctly with RestTemplate, what other options do I have?

Dknot
  • 63
  • 1
  • 8
  • I didn't read in details but at first sight, the root URI that you use with curl is not the same than the one you use in the RestTemplate. – Matteo NNZ May 02 '22 at 21:43
  • @MatteoNNZ yep, the uri is wrong, corrected it just now, but it did not fix the issue :c Gonna fix the question as well – Dknot May 02 '22 at 21:50
  • 1
    Its still wrong though. In the curl you're connecting to https://api.pinterest.com/v5/oauth/token, not to https://www.pinterest.com/v5/oauth/token – Matteo NNZ May 02 '22 at 21:52
  • @MatteoNNZ I feel stupid, but... yea, it fixed the issue. Idk what to say, I'm just grateful you found it, that would take me another couple hours if I would have noticed at all... – Dknot May 02 '22 at 22:02
  • When we write a lot of code we miss the biggest things, that's what code reviews exist for :) – Matteo NNZ May 02 '22 at 22:09

0 Answers0