Home  >  Q&A  >  body text

R interface to the Ghost CMS API

<p>I'm trying to connect to a local Ghost CMS instance from R using the built-in Admin API. There is a good documentation (https://ghost.org/docs/admin-api/#token-authentication) on how to connect in various languages, but unfortunately there is no documentation for R. I've written the following code but unfortunately am receiving a 401 error when trying to create a test article. Any help is greatly appreciated. <br /><br />R code:</p><p><strong></strong></p> <pre class="brush:php;toolbar:false;">api_admin_key <- "xxxxxx:yyyyyyyyyyyyyyy" api_admin_key <- unlist(strsplit(x = api_admin_key, split = ":")) names(api_admin_key) <- c("id", "secret") # Prepare header and payload iat <- as.integer(Sys.time()) header <- list(alg = 'HS256', typ = 'JWT', kid = api_admin_key[["id"]]) # Create the token (including decoding secret) payload <- jose::jwt_claim(iat = iat, exp = iat 5 * 60, aud = '/admin/') token <- jose::jwt_encode_hmac( claim = payload, secret = charToRaw(api_admin_key[["secret"]]), size = 256, header = header ) # Make an authenticated request to create a post url <- 'http://localhost:2368/ghost/api/admin/posts/' headers <- c('Authorization' = paste("Ghost", token)) body <- list(posts = list( "title" = 'Hello World', "html" = "<p>My post content. Work in progress...</p>", "status" = "published" ) ) httr::POST(url, body = body, encode = "json", httr::add_headers(.headers = headers))</pre> <p><br /></p>
P粉134288794P粉134288794444 days ago527

reply all(1)I'll reply

  • P粉739706089

    P粉7397060892023-08-04 09:11:43

    Looks like the problem is with the secret= parameter you passed to jwt_encode_hmac(). The charToRaw function cannot understand hexadecimal numbers, it only uses ASCII character codes. To do the conversion, you need to use one of the hex_to_raw functions from the existing question. I'm using a function here to do the conversion.

    hex_to_raw <- function(x) {
      digits <- strtoi(strsplit(x, "")[[1]], base=16L)
      as.raw(bitwShiftL(digits[c(TRUE, FALSE)],4) + digits[c(FALSE, TRUE)])
    }

    Also, you don't need to specify alg and typ in the header, because these will be added automatically by the function. So you can build your token using:

    api_admin_key <- "adam:12bd18f2cd12"
    
    api_admin_key <- unlist(strsplit(x = api_admin_key, split = ":"))
    names(api_admin_key) <- c("id", "secret")
    
    # Prepare header and payload
    iat <- as.integer(Sys.time())
    header <- list(kid = api_admin_key[["id"]])
    
    # Create the token (including decoding secret)
    payload <-
      jose::jwt_claim(iat = iat,
                      exp = iat + 5 * 60,
                      aud = '/admin/')
    
    token <-
      jose::jwt_encode_hmac(
        claim = payload,
        secret = hex_to_raw(api_admin_key[["secret"]]),
        size = 256,
        header = header
      )

    I tested each token using the debugger at https://jwt.io/ and they appear to be equivalent. In the debugger, the Base64 encoded value of the hexadecimal value "12bd18f2cd12" is "Er0Y8s0S".

    reply
    0
  • Cancelreply