【问题标题】:web browser authentication in GitHub Actions for Oauth tokenGitHub Actions 中用于 Oauth 令牌的 Web 浏览器身份验证
【发布时间】:2021-09-01 10:10:25
【问题描述】:

我正在尝试使用 GitHub Actions 通过 R 脚本使用 OAuth 2.0 令牌查询 GitHub API。当我运行代码时,它在我的本地计算机上运行良好,其中会弹出一个浏览器窗口,指示“正在等待浏览器中的身份验证...”,我可以手动关闭它。通过 GitHub Actions 运行时,工作流会挂在“正在等待浏览器中的身份验证...”,因为它位于远程计算机上。

我正在使用带有 httr 库的自定义 R 脚本。 API 凭据存储为我尝试查询的存储库的机密。

library(httr)

gh_key <- Sys.getenv('GH_KEY')
gh_secret <- Sys.getenv('GH_SECRET')

# setup app credentials
myapp <- oauth_app(appname = "data-in-r",
                   key = gh_key,
                   secret = gh_secret)

# get oauth credentials
github_token <- oauth2.0_token(oauth_endpoints('github'), app = myapp, cache = F)

# use api
gtoken <- config(token = github_token)

# get list of remote files in data folder
req <- GET("https://api.github.com/repos/tbep-tech/piney-point/contents/data", gtoken)

当脚本通过 GitHub Actions 运行时,如下所示,我不得不手动取消工作流,因为它在浏览器步骤被挂起。

是否有跳过浏览器步骤以便在 GitHub Actions 上运行的解决方法?有问题的仓库是here

【问题讨论】:

    标签: r oauth-2.0 github-actions httr


    【解决方案1】:

    您不能在像 Github Actions 这样的无头环境中使用 OAuth2.0 的 3-legged 变体(又名“网络应用程序流”)。

    如果您想使用 OAuth(我在下面列出了其他可能性),那么您需要利用 gitlab 所谓的“设备流”。见github documentation

    在此流程中,没有重定向到给定 URL,因此应用不需要浏览器窗口。相反,它向用户显示代码。用户必须在固定 URL (https://github.com/login/device) 上输入该代码。完成此操作后,应用程序可以请求身份验证令牌。 (所以应用程序必须不断轮询,直到用户输入代码)。

    不幸的是,httr 没有针对此变体的良好包装函数,因此您必须自己进行调用。它可以像这样工作:

    library(httr)
    
    
    
    app_id <- "*redacted*"
    
    
    r <- POST("https://github.com/login/device/code", 
              body = list(
                client_id = app_id,
                scope = "user repo delete_repo" #Scope must be given! https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps
    ))
    
    
    device_code <- content(r)$device_code
    
    print(paste0("Enter the code  ", content(r)$user_code, "  at ", content(r)$verification_uri))
    
    
    ## NOTE: In reality this request has to run in a loop, until the user has entered the code und the request succeeds.
    ##       For the demo we can execute it manually after the code has been entered.
    r <- POST("https://github.com/login/oauth/access_token", 
              body = list(
                client_id = app_id,
                device_code = device_code,
                grant_type = "urn:ietf:params:oauth:grant-type:device_code"
              ))
    
    token <- content(r)$access_token
    
    ## create and delete a private testrepository to check if everything worked
    r <- 
      POST("https://api.github.com/user/repos",
           add_headers(Authorization = paste("token", token)),
           body = list(name = "testrepo",
                     private = TRUE,
                     auto_init = FALSE), 
           encode = "json")
    
    
    r <- DELETE(paste0("https://api.github.com/repos/", content(r)$full_name), 
           add_headers(Authorization = paste("token", token)))
    

    我看到有httr2,它为这个流程提供了便利的功能。但是,我从未使用过它,也不知道它是否已经可靠运行。见here

    由于此流程仍需要用户交互,因此您最好使用以下变体之一(我不知道它们是否适合您的用例。):

    1. 基本身份验证: 您可以预先定义 github 所谓的“个人访问令牌”。使用此令牌,您无需进一步交互即可进行身份验证。创建被描述为here。在 R 中,您可以最轻松地与 httr::authenticate 一起使用它。

    2. GITHUB_TOKEN: Github 会自动创建特殊的秘密,特别是 Github Actions。这些可用于在包含的存储库中执行操作。如需更多信息,请参阅here

    【讨论】:

    • 非常棒的故障排除信息。我怀疑 OAuth2.0 无法满足我的需求。
    猜你喜欢
    • 2016-09-23
    • 1970-01-01
    • 1970-01-01
    • 2015-11-18
    • 2017-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-20
    相关资源
    最近更新 更多