Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deploying a Shiny app using gar_shiny_ui to shinyapps tries to redirect to localhost (and fails) #136

Closed
gilliganondata opened this issue Dec 31, 2018 · 8 comments

Comments

@gilliganondata
Copy link

gilliganondata commented Dec 31, 2018

What goes wrong

I have a Shiny app that runs locally, but, when I deploy to shinyapps.io, it gets through the permissions granting on the authentication screens but then redirects to a localhost URL with an error:

localhost refused to connect

The app is at https://gilligan.shinyapps.io/time-normalized/, FWIW. I don't think you'll be able to see much there.

Steps to reproduce the problem

Things I think I've done correctly, but which I suspect hold the key to the issue:

  • Have Web application credentials set up with both http://localhost and https://gilligan.shinyapps.io as authorized redirect URLs
  • I've downloaded the JSON file for those credentials and am using those both when running locally as well as am pushing them to shinyapps.io when I deploy the app. (For reference, the file is named ga-web-client.json and is stored in the same folder as the app.R file.)
  • I've authenticated (locally) and am using the .httr-oauth token file when I deploy as well (which may be where the issue lies?

A fully reproducible example might be a bit cumbersome. But, the relevant (I'm pretty sure) flow of the code is as follows:

library(shiny)
library(googleAuthR)

gar_set_client(web_json = "ga-web-client.json",
               scopes = c("https://www.googleapis.com/auth/analytics.readonly"))

library(googleAnalyticsR) 
library(tidyverse)

# If I *don't* include this, then the app -- when deployed to shinyapps.io -- immediately
# halts (grays out) as soon as it loads with the "Login" button.  
gar_auth(".httr-oauth")

## ui.R
ui <- fluidPage(title = "Time-Normalized Pageviews"
[additional UI code]
:

## server.R
server <- function(input, output, session){
  
  gar_shiny_auth(session)
  view_id <- callModule(authDropdown, "auth_menu", ga.table = ga_account_list)
[additional server code]
:
}

shinyApp(gar_shiny_ui(ui, login_ui = gar_shiny_login_ui), server)

When I deploy the app, I'm deploying three files (all of which are in the same directory):

deployApp(appFiles = c("app.R", "ga-web-client.json", ".httr-oauth"), appName = "time-normalized", appTitle = "Google Analytics - Time-Normalized Pageviews")

Session Info

R version 3.5.1 (2018-07-02)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS  10.14.1
googleAnalyticsR_0.5.0.9000 shiny_1.1.0
googleAuthR_0.7.0

I don't think this is a bug. I think I've just failed to quite put everything in its proper place and am having a hard time figuring out what exactly applies from the various notes and posts (there seems to be a bit more posted on the JS authentication option, but I'm trying to avoid that if possible).

@MarkEdmondson1234
Copy link
Owner

MarkEdmondson1234 commented Dec 31, 2018

Hi Tim,

I would remove gar_auth(".httr-oauth") as that will confuse things, only letting you authenticate for one user.

This is most likely related to an issue with shinyapps.io where it does not load the options set on loading the package, including your client ID/secret etc. Some discussion in this thread #74 which advises to set those arguments in an .Renviron file instead.

@gilliganondata
Copy link
Author

gilliganondata commented Dec 31, 2018

Thanks, Mark! I made some updates, and I'm back to having the app error out as soon as it loads.

The shinyapps.io log:

2018-12-31T14:40:57.280305+00:00 shinyapps[624885]: Listening on http://127.0.0.1:37324
2018-12-31T14:41:03.170269+00:00 shinyapps[624885]: Warning: Error in : Authentication options didn't match existing session token and not interactive session
2018-12-31T14:41:03.170273+00:00 shinyapps[624885]:            so unable to manually reauthenticate
2018-12-31T14:41:03.175500+00:00 shinyapps[624885]:   88: stop
2018-12-31T14:41:03.175502+00:00 shinyapps[624885]:   87: make_new_token
2018-12-31T14:41:03.175508+00:00 shinyapps[624885]:   79: ga.table
2018-12-31T14:41:03.175508+00:00 shinyapps[624885]:   78: <reactive>
2018-12-31T14:41:03.175503+00:00 shinyapps[624885]:   86: gar_auth
2018-12-31T14:41:03.175504+00:00 shinyapps[624885]:   85: get_google_token
2018-12-31T14:41:03.175505+00:00 shinyapps[624885]:   84: _f
2018-12-31T14:41:03.175505+00:00 shinyapps[624885]:   82: cachedHttrRequest
2018-12-31T14:41:03.175506+00:00 shinyapps[624885]:   81: memDoHttrRequest
2018-12-31T14:41:03.175507+00:00 shinyapps[624885]:   80: acc_sum
2018-12-31T14:41:03.175509+00:00 shinyapps[624885]:   62: pList
2018-12-31T14:41:03.175537+00:00 shinyapps[624885]:   13: runApp
2018-12-31T14:41:03.175510+00:00 shinyapps[624885]:   56: <observer>
2018-12-31T14:41:03.175539+00:00 shinyapps[624885]:   12: fn
2018-12-31T14:41:03.175540+00:00 shinyapps[624885]:    7: connect$retry
2018-12-31T14:41:03.175541+00:00 shinyapps[624885]:    6: eval
2018-12-31T14:41:03.175542+00:00 shinyapps[624885]:    5: eval

This was what I was seeing that led me to (erroneously) add in the gar_auth(".httr-oauth") line (which I've removed.

From reading through #74 , what I did was put an .Renviron in the same directory as my Shiny app. It looks like:

GAR_WEB_CLIENTID="XXXXXXXXXXX-XXXXXXXXXXb4vu05mergi9hbohnm.apps.googleusercontent.com"
GAR_WEB_CLIENT_SECRET="XXXXXXXXXXXXXXsI2StNT"
GAR_SCOPES="https://www.googleapis.com/auth/analytics.readonly"

I removed the gar_set_client() call (because environment variables with the names above automatically get picked up by googleAnalyticsR, right?).

I removed the gar_auth(".httr-oauth") call.

So, my app now looks like:

library(shiny)
library(googleAuthR)
library(googleAnalyticsR)  
library(tidyverse)

## ui.R
ui <- ...

(This runs fine locally.)

My deploy script:

deployApp(appFiles = c("app.R", ".Renviron"),
          appName = "time-normalized",
          appTitle = "Google Analytics - Time-Normalized Pageviews")

I tried deploying both with and without a .httr-oauth file with the same results.

Did I misunderstand something in the workaround to shinyapps.io not reading options?

Thanks for your help!

@gilliganondata
Copy link
Author

gilliganondata commented Dec 31, 2018

I feel like there are either multiple options for setting options, or I'm just struggling to figure out some shorthand. I've tried a number of different permutations -- always following the same process before deploying to shinyapps.io:

  1. Restarting R
  2. Deleting any .httr-oauth files
  3. Running locally and confirming that the Google project for which permission is being checked is not the default googleAnalyticsR and, instead, is the one I've set up.

I've uncovered a number of ways that I feel like I'm guessing.

Credentials: Web application vs. Other

I've got two sets of credentials set up: a "Web application" on and an "Other" one. Do I need both? I've started including options for both, and it seems like the "Other" one is the one that I'm getting prompted to provide permissions for when I run the app locally.

Setting the client ID(s), secret(s), and scope

I've created 5 variables in a .Renviron file that I'm uploading with app.R when I deploy my app to shinyapps.io.

GAR_WEB_CLIENTID="[Web application client ID]"
GAR_WEB_CLIENT_SECRET="[Web application client secret]"
GAR_CLIENTID="['Other' client ID]"
GAR_CLIENT_SECRET="['Other' client secret]"
GAR_SCOPES="https://www.googleapis.com/auth/analytics.readonly"

I'm not entirely sure I'm then accessing those values correctly. I'd thought at one point that, if they existed with those specific names in the .Renviron file that googleAuthR would load them in automatically without needing to actually set any options. But...no?

So, my code looks like this:

library(googleAuthR)

# Should it be this...
options("googleAuthR.client_id" = Sys.getenv("GAR_CLIENTID"))
options("googleAuthR.client_secret" = Sys.getenv("GAR_CLIENT_SECRET"))
options("googleAuthR.webapp.client_id" = Sys.getenv("GAR_WEB_CLIENTID"))
options("googleAuthR.webapp.client_secret" = Sys.getenv("GAR_WEB_CLIENT_SECRET"))
options("googleAuthR.scopes.selected" = Sys.getenv("GAR_SCOPES"))

# ...or this? I've tried both, as well as included both -- figuring I would start removing different bits if
# and when I got it working.
options(googleAuthR.client_id = Sys.getenv("GAR_CLIENTID"),
        googleAuthR.client_secret = Sys.getenv("GAR_CLIENT_SECRET"),
        googleAuthR.webapp.client_id = Sys.getenv("GAR_WEB_CLIENTID"),
        googleAuthR.webapp.client_secret = Sys.getenv("GAR_WEB_CLIENT_SECRET"),
        googleAuthR.scopes.selected = Sys.getenv("GAR_SCOPES"))

library(googleAnalyticsR) 

To upload .httr-oauth or not?

I think I shouldn't need/want to upload .httr-oauth, as that's the auth to actually access the data. But, I've tried both ways with no luck.

The error in shinyapps.io

I continue to see the "...didn't match existing session token..." error in the shinyapps.io logs:

2018-12-31T18:23:20.024181+00:00 shinyapps[624885]: Listening on http://127.0.0.1:41153
2018-12-31T18:23:27.146474+00:00 shinyapps[624885]: Warning: Error in : Authentication options didn't match existing session token and not interactive session
2018-12-31T18:23:27.146477+00:00 shinyapps[624885]:            so unable to manually reauthenticate
2018-12-31T18:23:27.151985+00:00 shinyapps[624885]:   89: stop
2018-12-31T18:23:27.151987+00:00 shinyapps[624885]:   88: make_new_token
2018-12-31T18:23:27.151989+00:00 shinyapps[624885]:   87: gar_auth
2018-12-31T18:23:27.151989+00:00 shinyapps[624885]:   86: get_google_token
2018-12-31T18:23:27.151990+00:00 shinyapps[624885]:   85: _f
2018-12-31T18:23:27.151991+00:00 shinyapps[624885]:   83: cachedHttrRequest
2018-12-31T18:23:27.151991+00:00 shinyapps[624885]:   82: memDoHttrRequest
2018-12-31T18:23:27.151992+00:00 shinyapps[624885]:   80: gar_api_page
2018-12-31T18:23:27.151993+00:00 shinyapps[624885]:   79: ga.table
2018-12-31T18:23:27.151994+00:00 shinyapps[624885]:   78: <reactive>
2018-12-31T18:23:27.151992+00:00 shinyapps[624885]:   81: f
2018-12-31T18:23:27.151994+00:00 shinyapps[624885]:   62: pList
2018-12-31T18:23:27.151995+00:00 shinyapps[624885]:   56: <observer>
2018-12-31T18:23:27.151995+00:00 shinyapps[624885]:   13: runApp
2018-12-31T18:23:27.151996+00:00 shinyapps[624885]:   12: fn
2018-12-31T18:23:27.151997+00:00 shinyapps[624885]:    7: connect$retry
2018-12-31T18:23:27.151997+00:00 shinyapps[624885]:    6: eval
2018-12-31T18:23:27.151998+00:00 shinyapps[624885]:    5: eval

I appreciate your help! My hope is that I'll get to something that is clean and reliable and I won't just be embarrassed for having opened this issue.

@MarkEdmondson1234
Copy link
Owner

Oh is it only using your own GA data? In that case just upload the auth file you have locally, and no need for any Shiny specific auth at all :) call ga_auth() as you would locally.

@gilliganondata
Copy link
Author

The intention is to have it allow a user to authenticate and then use their own data. I'm pretty sure I just got lost in a series of troubleshooting posts and took that wrong turn. So... I definitely don't want to be uploading a httr-oauth, it sounds like? (That seems so obvious in hindsight.) But, I'm still stuck when it comes to getting shinyapps.io to allow authentication -- it just crashes out immediately with the Error in : Authentication options didn't match existing session token and not interactive session so unable to manually reauthenticate error.

@MarkEdmondson1234
Copy link
Owner

MarkEdmondson1234 commented Jan 1, 2019

I think for now use the older methods or JavaScript authentication, it seems shinyapps.io needs some special configurations I will do on googleAuthR end to fix it. Sorry about that, its a bug as I guess shinyapps.io is a popular platform, it works on my local Shiny server but not shinyapps.io specifically.

I've confirmed the older methods work though with shinyapps.io still. e.g.

#server 
library(shiny)
library(googleAuthR)
library(googleAnalyticsR)

options(shiny.port = 1221) # for local testing
options(googleAuthR.webapp.client_id = "xxx") # web application client id
options(googleAuthR.webapp.client_secret = "xxxx")
options(googleAuthR.scopes.selected = c("https://www.googleapis.com/auth/analytics.readonly"))

function(input, output, session){
  
  #####--------- Setup
  
  token <- callModule(googleAuth, "login")

  ga_accounts <- reactive({
    validate(
      need(token(), "Authenticate")
    )
    
    with_shiny(google_analytics_account_list, shiny_access_token = token())
  })

etc..

and

#ui 
library(shiny)
library(googleAuthR)
library(googleAnalyticsR)

navbarPage("GA v4 API",
           tabPanel("Setup", tabName = "setup", ,
                    googleAuthUI("login"),
                    authDropdownUI("auth_menu")
           ),
etc.

@MarkEdmondson1234
Copy link
Owner

MarkEdmondson1234 commented Jan 1, 2019

But, it does work now with the new method if the latest version of googleAuthRis installed: you just have to specify the redirect yourself in a new option. The below works, note the new googleAuthR.redirect option which should be set to the same URL you put in the Google project redirect origin field.

This is live at this URL: https://mark.shinyapps.io/googleAnalyticsR_test_deployment/

library(shiny)
library(googleAuthR)
library(googleAnalyticsR) 

gar_set_client(web_json = "ga-web-client.json",
               scopes = "https://www.googleapis.com/auth/analytics.readonly")

options(googleAuthR.redirect = "https://mark.shinyapps.io/googleAnalyticsR_test_deployment/")

## ui.R
ui <- fluidPage(title = "googleAnalyticsR Test Deployment",
                
      authDropdownUI("auth_menu"),
      textOutput("viewid"),
      textOutput("client_id")
      
)

## server.R
server <- function(input, output, session){

  gar_shiny_auth(session)
  
  al <- reactive(ga_account_list())
  view_id <- callModule(authDropdown, "auth_menu", ga.table = al)
  
  output$viewid <- renderText(view_id())
  
  output$client_id <- renderText(getOption("googleAuthR.webapp.client_id"))

}

shinyApp(gar_shiny_ui(ui, login_ui = silent_auth), server)

@gilliganondata
Copy link
Author

gilliganondata commented Jan 1, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants