Authentication implemented in R

For anybody interested in reading from a pod using the R programming language, I’ve got a barebones implementation of authentication working here: Login to an Identity Provider and request resource from a Solid Pod using DPoP · GitHub

It tries to integrate with the httr2 R package, on which it builds, though I haven’t fully gotten my head around that package’s architecture yet, so I’m sure the integration can be improved…

1 Like

I had planned to give it a try with a colleague of mine in december.

It works.
Now I’m going to see how to best access the information on the pod, and see how to best read and write data from and to it.

If that works, It may be interesting to see if I can pull data from google drive (R has functions to reach it) and see how to transfer it to a pod.

[edit] some feedback: There is a timeout (which is probably editable if needed).
I tried to write some data in my pod, but got some errors

request(“https://[linktomydatapod/folder/subfolder/manual%20copy%20paste”) %>%
req_auth_solid_dpop(solid_session) %>%
req_body_raw(content_02) %>%

Error: HTTP 401 Unauthorized.
OAuth error: invalid_token - Invalid PoP token
scope: openid webid

Don’t have enough programming experience to figure out where the problem might lie.

1 Like


I’ve found the httr2 interface a little unfamiliar, but quite powerful.
It would be good to create an R package with a couple of extra features, including caching of tokens and automatic refresh of tokens, a higher level interface for basic requests, and integration with rdf libraries.

I haven’t tested a write yet, so you’re on new ground for this code.
If you’re going to use it at its current level of maturity, I’d suggest stepping through the functions line by line while following the Solid OIDC Primer
There’s still lots of places things could be going wrong, and the error messages from the server are rather terse - the only way to debug is to know the spec…

Edit: as it happens, this error is easy to identify. L164 hardcodes the request type as a GET. This needs to be changed to use the request type for the req object, i.e. POST or PATCH depending on what content you’re writing.

1 Like

I’ve now done a substantial rewrite to better align with httr2, though a full alignment is not possible with the way it’s currently setup.

The user now dynamically registers a client with solid_client_register_dyn and the function req_oauth_solid_dpop transparently calls the authorisation flow, caches the access token (in memory for the moment), tests expiry and requests a new one with the refresh_token.

Examples are given for PUT, POST and PATCH too.

Note that this would presumably actually give a 404 error even when authorised. A POST creates a new resource in a container either with a URI issued by the server or using a slug provided in a header.
In this case, a slug is not provided, so the server would try to create a new randomly named resource in “manual%20copy%20paste”, and fail to do so unless it already exists as a container.
Using PUT would have the intended effect of creating a new resource named “manual%20copy%20paste” but a content type would still need to be provided otherwise the server would return an error 400.

There’s still a fair bit of work to do to make this R code user friendly :slight_smile: