Skip to content

Instantly share code, notes, and snippets.

@MarkEdmondson1234
Last active October 5, 2018 13:42
Show Gist options
  • Save MarkEdmondson1234/d55214692ba4f96824a9 to your computer and use it in GitHub Desktop.
Save MarkEdmondson1234/d55214692ba4f96824a9 to your computer and use it in GitHub Desktop.
Google OAuth2 Authentication functions for an R Shiny app
## GUIDE TO AUTH2 Authentication in R Shiny (or other online apps)
##
## Mark Edmondson 2015-02-16 - @HoloMarkeD | http://markedmondson.me
##
## v 0.1
##
##
## Go to the Google API console and activate the APIs you need. https://code.google.com/apis/console/?pli=1
## Get your client ID, and client secret for use below, and put in the URL of your app in the redirect URIs
## e.g. I put in https://mark.shinyapps.io/ga-effect/ for the GA Effect app,
## and http://127.0.0.1:6423 for local testing (start the Shiny App by using this command to force the port: runApp(port=6423)
##
## I then have an auth.r file I source which is below
##
## auth.r
CLIENT_ID <- "YOUR CLIENT ID"
CLIENT_SECRET <- "YOUR CLIENT SECRET"
CLIENT_URL <- 'https://your-url-that-picks-up-return-token.com'
# CLIENT_URL <- 'http://127.0.0.1:6423' # I comment this out for deployment, in for local testing
### Authentication functions
## generate the URL the user clicks on.
## The redirect URL is then returned to with the extra 'code' and 'state' URL parameters appended to it.
ShinyGetTokenURL <- function(client.id = CLIENT_ID,
client.secret = CLIENT_SECRET,
redirect.uri = CLIENT_URL) {
url <- paste('https://accounts.google.com/o/oauth2/auth?',
'scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fanalytics+', ## plus any other scopes you need
'https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fanalytics.readonly&',
'state=securitytoken&',
'redirect_uri=', redirect.uri, '&',
'response_type=code&',
'client_id=', client.id, '&',
'approval_prompt=auto&',
'access_type=online', sep='', collapse='');
return(url)
}
## gets the token from Google once you have the code that is in the return URL
ShinyGetToken <- function(code,
client.id = CLIENT_ID,
client.secret = CLIENT_SECRET,
redirect.uri = CLIENT_URL){
token <- MErga.authenticate(client.id = client.id,
client.secret = client.secret,
code = code,
redirect.uri = redirect.uri);
return(token)
}
## posts your code to google to get the current refresh
MErga.authenticate <- function(client.id, client.secret, code, redirect.uri) {
opts <- list(verbose = FALSE);
raw.data <- postForm('https://accounts.google.com/o/oauth2/token',
.opts = opts,
code = code,
client_id = client.id,
client_secret = client.secret,
redirect_uri = redirect.uri,
grant_type = 'authorization_code',
style = 'POST');
token.data <- fromJSON(raw.data);
now <- as.numeric(Sys.time());
token <- c(token.data, timestamp = c('first'=now, 'refresh'=now));
return(token);
}
#### end auth.r
#### Then in Shiny these are the appropriate server.r and ui.r functions
##
## server.r
#
shinyServer(function(input, output, session) {
### Authentication Functions ########################################################
##
## AuthCode() - checks for presence of code in URL
## AccessToken() - creates a token once a code is available
## ShinyMakeGAProfileTable - the table of profiles taken from API
## output$AuthGAURL - creates the authentication URL
## output$GAProfile - table of the profiles belonging to user
AuthCode <- reactive({
## gets all the parameters in the URL. Your authentication code should be one of them
pars <- parseQueryString(session$clientData$url_search)
if(length(pars$code) > 0){
return(pars$code)
}
})
AccessToken <- reactive({
validate(
need(AuthCode(), "Authenticate To See")
)
access_token <- ShinyGetToken(code = AuthCode())
token <- access_token$access_token
})
output$AuthGAURL <- renderUI({
a("Click Here to Authorise Your Google Analytics Access", href=ShinyGetTokenURL())
})
ShinyMakeGAProfileTable <- reactive({
token <- AccessToken()
### ... do your call to the Google API with the token .. etc.
})
## end server.r
## ui.r just provides the URL for users to click
## ui.r
# ...
uiOutput("AuthGAURL")
# ...
## end ui.r
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment