I have data in a Microsoft Dataverse that I'm attempting to pull into R. I don't have much background in software development / APIs / OAuth so I first used a tutorial that showed me how to work with APIs in Postman. I then used several tutorials online (most notably this one) to try to replicate what I'm doing in Postman. Doing so, I came up with the code below:
require(httr)
require(rvest)
dataverse_api = oauth_endpoint(request = NULL,
authorize = https://login.microsoftonline.com/REDACTED/oauth2/v2.0/authorize,
access = https://login.microsoftonline.com/REDACTED/oauth2/v2.0/token,
base_url = https://login.microsoftonline.com/common/oauth2/authorize?resourcehttps://org593dc393.crm4.dynamics.com)
API.Key = "REDACTED"
API.Secret = "REDACTED"
App = oauth_app("EPS Project Development", key = API.Key, secret = API.Secret)
API.token = oauth2.0_token(dataverse_api, App, scope = https://org593dc393.crm4.dynamics.com/.default)
API.AuthKey = API.token$credentials$access_token
GET.Buildings = GET(https://org593dc393.crm4.dynamics.com/api/data/v9.2/crfd0_dartbuildingses, add_headers(Authorization = paste("Bearer", API.AuthKey, sep = " ")))
The first day, the code above worked, and I was so excited! The next day, with no changes to the code, it returned a response of 401 (unauthorized). I've been going back and forth between Postman and R trying to figure out what's different, and what I realized is that every time I authenticate in Postman, I get a completely new access token (as expected); however, in R, when I keep running this code, the parameter stored in API.token$credentials$access_token
is the same. I'm not really sure why this is.
Doing some more research, it seems like maybe I need a refresh token? I don't understand that because this is the same code other developers posted and no one else seems to be mentioning that it will only work once and then never again without a refresh token. Moreover, inspecting the documentation for httr makes it seem as if part of the oauth2.0_token function is to check whether or not the token needs to be refreshed. Anyway, when I look at the parameter API.token$refresh()
, it tells me Error: Refresh token not available
.
So now I'm attempting to get a refresh token, again without really understanding why. The documentation on the httr package details a function called oauth-refresh, but ?oauth-refresh
gives an error and ?oauth_refresh
says no results found. I also looked into this package by MatthewJWhittle that has a function called refresh_token, but again the help functions turn up no results after installing the package, so I guess it's no longer a valid package.
TLDR: Why is my code coming back with the same access token every time I request authorization? Did I miss a step in the code where I'm supposed to request a refresh token? Or if this is by design, how do I get a new one once this one expires?
It turns out I just needed to add cache = FALSE
so that I'm not using cached tokens. If it's helpful to anyone, the full code is now:
require(httr)
require(rvest)
dataverse_api = oauth_endpoint(request = NULL,
authorize = https://login.microsoftonline.com/REDACTED/oauth2/v2.0/authorize,
access = https://login.microsoftonline.com/REDACTED/oauth2/v2.0/token,
base_url = https://login.microsoftonline.com/common/oauth2/authorize?resourcehttps://org593dc393.crm4.dynamics.com)
API.Key = "REDACTED"
API.Secret = "REDACTED"
App = oauth_app("EPS Project Development", key = API.Key, secret = API.Secret)
API.token = oauth2.0_token(dataverse_api, App, scope = https://org593dc393.crm4.dynamics.com/user_impersonation, cache = FALSE)
API.AuthKey = API.token$credentials$access_token
GET.Buildings = GET(https://org593dc393.crm4.dynamics.com/api/data/v9.2/crfd0_dartbuildingses, add_headers(Authorization = paste("Bearer", API.AuthKey, sep = " ")))