question

jonathan avatar image
jonathan asked skodama answered

server to server oauth process

I am reading the document https://docs.clover.com/build/web-app...

I am trying to understand how a web application could connect without user intervention. The process defined in the document seems to be geared for an employee to login. For example, if I have a web application that is going to display to the public the menu for the restaurant, I do not want the customer who has no access to clover to need to authenticate. I want the server to authenticate and retrieve the menu data.

I would expect something like this:

var client = new RestClient("http://example.com/myapi/oauth/token"); 
RestRequest request = new RestRequest() { Method = Method.POST };

request.AddHeader("Content-Type", "application/json");
 request.AddParameter("grant_type", "client_credentials"); 
request.AddParameter("client_id", "client-app"); 
request.AddParameter("client_secret", "secret");

var response = client.Execute(request);

I see this method in the documents: https://www.clover.com/oauth/token

However, it appears to depend on a "code" parameter which is the result of a redirect action from user input.

Am I missing something here about how to make a server to server OAuth call?

OAuth
10 |2000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

1 Answer

skodama avatar image
skodama answered

We have a batch program that retrieves and updates item data using the Oauth authentication.

What we do is first initialize the HttpClient with necessary configurations, then send a login request using that HttpClient, and then send the request for the token using the same HttpClient. It is essential to use the same HttpClient for this method to work (because of cookies). The redirection does not really matter in our method.

This is a little hacky and it must be done at server side, so I'm not sure if it helps in your case.

private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1";
private static final String BASE_URL = "https://www.clover.com";                                                               private static HttpClient initializeClient() throws Exception
{
    RequestConfig globalConfig = RequestConfig.custom()
            .setCookieSpec(CookieSpecs.STANDARD)
            .build();
    CookieStore cookieStore = new BasicCookieStore();
    HttpClient client = HttpClientBuilder.create()
            .setUserAgent(USER_AGENT)
            .setDefaultRequestConfig(globalConfig)
            .setDefaultCookieStore(cookieStore)
            .build();

    return client;
}

private static String login(HttpClient client, String login_user, String login_pw, String client_id, String redirect_url) throws Exception
{
    HttpPost post = new HttpPost(BASE_URL + "/cos/v1/dashboard/login?_csrfToken=");
    post.setHeader("Accept-Language", "en-US,en;q=0.5");
    post.setHeader("Connection", "keep-alive");
    post.setHeader("Referer", "https://www.clover.com/oauth/authorize?response_type=token&client_id=CLIENT_ID");
    post.setHeader("Accept", "application/json, text/javascript, */*; q=0.01");
    post.setHeader("Content-Type", "application/json; charset=UTF-8");
    post.setEntity(new StringEntity("{\"email\":\"" + login_user + "\",\"password\":\"" + login_pw + "\"}"));
    post.setHeader("Accept-Encoding", "gzip, deflate");
    post.setHeader("Host", "www.clover.com");

    HttpResponse resp = client.execute(post);

    if (resp.getStatusLine().getStatusCode() != HttpStatus.SC_OK)
        throw new IOException(resp.getStatusLine().toString());


    InputStream in = resp.getEntity().getContent();
    String response = getResult(in);

    JsonObject jsonObject = new JsonParser().parse(response).getAsJsonObject();
    JsonObject merchantObject = jsonObject.getAsJsonObject("account").getAsJsonObject("primaryMerchant");
    String merchantId = "";
    if(merchantObject != null)
    {
        merchantId = merchantObject.get("id").getAsString();
    }
    System.out.println("MerchantID: " + merchantId);

    return merchantId;
}


private static String getAccessToken(HttpClient client, String client_id, String merchant_id) throws Exception
{
    String accessToken = "";
    HttpGet method = new HttpGet(BASE_URL + "/a/" + client_id + "?merchant_id=" + merchant_id + "&response_type=token");
    method.setHeader("Referer", BASE_URL + "/oauth/merchants/" + merchant_id);
    method.setHeader("Host", "www.clover.com");

    HttpClientContext context = HttpClientContext.create();
    HttpResponse resp = client.execute(method, context);

    if (resp.getStatusLine().getStatusCode() != HttpStatus.SC_OK)
        throw new IOException(resp.getStatusLine().toString());

    HttpUriRequest currentReq = (HttpUriRequest) context.getAttribute(HttpClientContext.HTTP_REQUEST);
    HttpHost currentHost = (HttpHost)  context.getAttribute(HttpClientContext.HTTP_TARGET_HOST);
    String currentUrl = (currentReq.getURI().isAbsolute()) ? currentReq.getURI().toString() : (currentHost.toURI() + currentReq.getURI());
    System.out.println("Current Context URL: " + currentUrl);

    List<URI> redirectURIs = context.getRedirectLocations();
    if (redirectURIs != null && !redirectURIs.isEmpty()) 
    {
        for (URI redirectURI : redirectURIs) {
            System.out.println("Redirect URI: " + redirectURI);
        }
        URI finalURI = redirectURIs.get(redirectURIs.size() - 1);
        String url = finalURI.toString();
        if(url != null)
        {
            accessToken = url.substring(url.indexOf("access_token=") + "access_token=".length());
            System.out.println("Token: " + accessToken);
        }
        System.out.println("Final Context URL: " + finalURI.toString());
    }       
    return accessToken;
}
10 |2000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Welcome to the
Clover Developer Community