Introdução
Este tutorial demonstra como criar um botão "Logon com o GitHub" para um site. O site usará um GitHub App para gerar um token de acesso do usuário por meio do fluxo do aplicativo Web. Em seguida, o site usa o token de acesso do usuário para fazer solicitações de API em nome do usuário autenticado.
Este tutorial usa o Ruby, mas você pode usar o fluxo de aplicativo Web com qualquer linguagem de programação usada para o desenvolvimento na Web.
Sobre o fluxo de aplicativos Web e tokens de acesso do usuário
Seu aplicativo deve usar um token de acesso do usuário se você quiser atribuir as ações do aplicativo a um usuário. Para obter mais informações, confira "Autenticação com um aplicativo GitHub em nome de um usuário".
Há duas maneiras de gerar um token de acesso do usuário para um GitHub App: fluxo de aplicativo Web e fluxo de dispositivo. Se o aplicativo tiver acesso a uma interface da Web, você deverá usar o fluxo do aplicativo Web. Se o aplicativo não tiver acesso a uma interface da Web, use o fluxo do dispositivo. Para obter mais informações, confira "Como gerar um token de acesso do usuário para um GitHub App" e "Criando uma CLI com um Aplicativo GitHub."
Pré-requisitos
Este tutorial pressupõe que você já tenha registrado o GitHub App. Para obter mais informações sobre como registrar um GitHub App, confira "Registrar um Aplicativo GitHub".
Antes de seguir este tutorial, você precisa definir uma URL de retorno de chamada para o aplicativo. Este tutorial usa um servidor local do Sinatra com a URL padrão http://localhost:4567
. Por exemplo, para trabalhar com a URL padrão de um aplicativo local do Sinatra, a URL de retorno de chamada pode ser http://localhost:4567/github/callback
. Quando estiver pronto para implantar seu aplicativo, altere a URL de retorno de chamada para usar o endereço do servidor dinâmico. Para obter mais informações sobre como atualizar a URL de retorno de chamada do seu aplicativo, confira "Modificar um registro do Aplicativo GitHub" e "Sobre a URL de retorno de chamada de autorização do usuário".
Este tutorial pressupõe que você tenha uma compreensão básica do Ruby e do sistema de modelos do Ruby, o ERB. Para obter mais informações, confira Ruby e ERB.
Instalar dependências
Este tutorial usa o Ruby gem Sinatra para criar um aplicativo Web com o Ruby. Para obter mais informações, confira o LEIAME do Sinatra.
Este tutorial usa o Ruby Gem dotenv para acessar valores armazenados em um arquivo .env
. Para obter mais informações, confira o LEIAME do dotenv.
Para seguir este tutorial, você precisa instalar os gems Sinatra e dotenv no projeto Ruby. Por exemplo, faça isso com o Bundler:
-
Caso ainda não tenha o Bundler instalado, execute o seguinte comando no terminal:
gem install bundler
-
Caso ainda não tenha um Gemfile para seu aplicativo, execute o seguinte comando no terminal:
bundle init
-
Caso ainda não tenha um Gemfile.lock para seu aplicativo, execute o seguinte comando no terminal:
bundle install
-
No terminal, instale os gems executando os seguintes comandos:
bundle add sinatra
bundle add dotenv
Armazenar a ID do cliente e o segredo do cliente
Este tutorial mostrará como armazenar a ID do cliente e o segredo do cliente em variáveis de ambiente e acessá-los com ENV.fetch
. Quando você implantar seu aplicativo, o ideal será alterar a forma como armazena a ID do cliente e o segredo do cliente. Para obter mais informações, confira "Armazenar o segredo do cliente com segurança".
-
No canto superior direito de qualquer página do GitHub, clique na foto do seu perfil.
-
Acesse as configurações da sua conta.
- Para um aplicativo de propriedade de uma conta pessoal, clique em Configurações.
- Para um aplicativo de propriedade de uma organização:
- Clique em Suas organizações.
- À direita da organização, clique em Configurações.
-
Na barra lateral esquerda, clique em Configurações do desenvolvedor.
-
Na barra lateral esquerda, clique em GitHub Apps .
-
Ao lado do GitHub App com o qual deseja trabalhar, clique em Editar.
-
Na página de configurações do aplicativo, encontre a ID do cliente para seu aplicativo. Você a adicionará a um arquivo
.env
em uma etapa posterior. Observe que a ID do cliente é diferente da ID do aplicativo. -
Na página de configurações do aplicativo, clique em Gerar um novo segredo do cliente. Você adicionará o segredo do cliente a um arquivo
.env
em uma etapa posterior. -
Crie um arquivo chamado
.env
no mesmo nível doGemfile
. -
Se o projeto ainda não tiver um arquivo
.gitignore
, crie um arquivo.gitignore
no mesmo nível doGemfile
. -
Adicione
.env
ao arquivo.gitignore
. Isso impedirá você de fazer um commit acidental do segredo do cliente. Para obter mais informações sobre os arquivos.gitignore
, confira "Ignorar arquivos". -
Adicione o conteúdo a seguir ao arquivo
.env
. SubstituaYOUR_CLIENT_ID
pela ID do cliente do aplicativo. SubstituaYOUR_CLIENT_SECRET
pelo segredo do cliente do seu aplicativo.CLIENT_ID="YOUR_CLIENT_ID" CLIENT_SECRET="YOUR_CLIENT_SECRET"
Adicionar o código para gerar um token de acesso do usuário
Para obter um token de acesso do usuário, primeiro, você precisa solicitar que o usuário autorize seu aplicativo. Quando um usuário autoriza seu aplicativo, ele é redirecionado para a URL de retorno de chamada do aplicativo. A solicitação para a URL de retorno de chamada inclui um parâmetro de consulta code
. Quando seu aplicativo recebe uma solicitação para atender a essa URL de retorno de chamada, você pode trocar o parâmetro code
por um token de acesso do usuário.
Estas etapas orientam você na escrita do código usado para gerar um token de acesso do usuário. Para ir para o código final, confira "Exemplo de código completo".
-
No mesmo diretório do arquivo
.env
, crie um arquivo Ruby para manter o código que vai gerar um token de acesso do usuário. Este tutorial dará ao arquivo o nomeapp.rb
. -
No início do
app.rb
, adicione estas dependências:Ruby require "sinatra" require "dotenv/load" require "net/http" require "json"
require "sinatra" require "dotenv/load" require "net/http" require "json"
As dependências
sinatra
edotenv/load
usam os gems que você instalou anteriormente.net/http
ejson
fazem parte da biblioteca padrão do Ruby. -
Adicione o código a seguir a
app.rb
para obter a ID do cliente do aplicativo e o segredo do cliente do arquivo.env
.Ruby CLIENT_ID = ENV.fetch("CLIENT_ID") CLIENT_SECRET = ENV.fetch("CLIENT_SECRET")
CLIENT_ID = ENV.fetch("CLIENT_ID") CLIENT_SECRET = ENV.fetch("CLIENT_SECRET")
-
Adicione o código a seguir a
app.rb
para exibir um link que solicitará aos usuários que autentiquem seu aplicativo.Ruby get "/" do link = '<a href="http(s)://HOSTNAME/login/oauth/authorize?client_id=<%= CLIENT_ID %>">Login with GitHub</a>' erb link end
get "/" do link = '<a href="http(s)://HOSTNAME/login/oauth/authorize?client_id=<%= CLIENT_ID %>">Login with GitHub</a>' erb link end
-
Adicione o código a seguir a
app.rb
para processar as solicitações à URL de retorno de chamada do aplicativo e obter o parâmetrocode
da solicitação. SubstituaCALLBACK_URL
pela URL de retorno de chamada do seu aplicativo, menos o domínio. Por exemplo, se a URL de retorno de chamada forhttp://localhost:4567/github/callback
, substituaCALLBACK_URL
por/github/callback
.Ruby get "CALLBACK_URL" do code = params["code"] render = "Successfully authorized! Got code #{code}." erb render end
get "CALLBACK_URL" do code = params["code"] render = "Successfully authorized! Got code #{code}." erb render end
Atualmente, o código só renderiza uma mensagem com o parâmetro
code
. As etapas a seguir expandirão esse bloco de código. -
Opcionalmente, verifique seu progresso:
app.rb
agora tem esta aparência, sendo queCALLBACK_URL
é a URL de retorno de chamada do seu aplicativo, menos o domínio:Ruby require "sinatra" require "dotenv/load" require "net/http" require "json" CLIENT_ID = ENV.fetch("CLIENT_ID") CLIENT_SECRET = ENV.fetch("CLIENT_SECRET") get "/" do link = '<a href="http(s)://HOSTNAME/login/oauth/authorize?client_id=<%= CLIENT_ID %>">Login with GitHub</a>' erb link end get "CALLBACK_URL" do code = params["code"] render = "Successfully authorized! Got code #{code}." erb render end
require "sinatra" require "dotenv/load" require "net/http" require "json" CLIENT_ID = ENV.fetch("CLIENT_ID") CLIENT_SECRET = ENV.fetch("CLIENT_SECRET") get "/" do link = '<a href="http(s)://HOSTNAME/login/oauth/authorize?client_id=<%= CLIENT_ID %>">Login with GitHub</a>' erb link end get "CALLBACK_URL" do code = params["code"] render = "Successfully authorized! Got code #{code}." erb render end
-
No terminal, no diretório em que
app.rb
está armazenado, executeruby app.rb
. Um servidor local do Sinatra deve ser iniciado. -
No navegador, navegue até
http://localhost:4567
. Você verá um link com o texto "Faça logon com o GitHub". -
Clique no link "Fazer logon com o GitHub".
Caso não tenha autorizado o aplicativo, se você clicar no link, será levado para
http(s)://HOSTNAME/login/oauth/authorize?client_id=CLIENT_ID
, sendo queCLIENT_ID
é a ID do cliente do aplicativo. Essa é uma página do GitHub que solicita aos usuários a autorizar seu aplicativo. Se você clicar no botão para autorizar seu aplicativo, acessará a URL de retorno de chamada do aplicativo.Se você autorizou seu aplicativo anteriormente e a autorização não foi revogada, o prompt de autorização é ignorado e leva você diretamente para a URL de retorno de chamada. Você poderá revogar sua autorização anterior se quiser ver a solicitação de autorização. Para obter mais informações, confira "Revisar e revogar a autorização dos Aplicativos GitHub".
-
A página da URL de retorno de chamada, acessada com um clique no link "Fazer logon com o GitHub" e com a autorização do aplicativo, se solicitado, exibirá um texto semelhante a "Autorizado com sucesso! Código agc622abb6135be5d1f2 recebido".
-
No terminal em que o Sinatra está em execução, interrompa o servidor inserindo CTRL+C.
-
-
Substitua o conteúdo de
app.rb
pelo código a seguir, sendo queCALLBACK_URL
é a URL de retorno de chamada do seu aplicativo, menos o domínio.Esse código adiciona a lógica para trocar o parâmetro
code
por um token de acesso do usuário:- A função
parse_response
analisa a resposta da API do GitHub. - A função
exchange_code
troca o parâmetrocode
por um token de acesso do usuário. - O manipulador para a solicitação de URL de retorno de chamada agora chama
exchange_code
para trocar o parâmetro de código por um token de acesso do usuário. - A página de retorno de chamada agora mostra o texto para indicar que um token foi gerado. Se a geração do token não tiver sido bem-sucedida, a página indicará essa falha.
Ruby require "sinatra" require "dotenv/load" require "net/http" require "json" CLIENT_ID = ENV.fetch("CLIENT_ID") CLIENT_SECRET = ENV.fetch("CLIENT_SECRET") def parse_response(response) case response when Net::HTTPOK JSON.parse(response.body) else puts response puts response.body {} end end def exchange_code(code) params = { "client_id" => CLIENT_ID, "client_secret" => CLIENT_SECRET, "code" => code } result = Net::HTTP.post( URI("http(s)://HOSTNAME/login/oauth/access_token"), URI.encode_www_form(params), {"Accept" => "application/json"} ) parse_response(result) end get "/" do link = '<a href="http(s)://HOSTNAME/login/oauth/authorize?client_id=<%= CLIENT_ID %>">Login with GitHub</a>' erb link end get "CALLBACK_URL" do code = params["code"] token_data = exchange_code(code) if token_data.key?("access_token") token = token_data["access_token"] render = "Successfully authorized! Got code #{code} and exchanged it for a user access token ending in #{token[-9..-1]}." erb render else render = "Authorized, but unable to exchange code #{code} for token." erb render end end
require "sinatra" require "dotenv/load" require "net/http" require "json" CLIENT_ID = ENV.fetch("CLIENT_ID") CLIENT_SECRET = ENV.fetch("CLIENT_SECRET") def parse_response(response) case response when Net::HTTPOK JSON.parse(response.body) else puts response puts response.body {} end end def exchange_code(code) params = { "client_id" => CLIENT_ID, "client_secret" => CLIENT_SECRET, "code" => code } result = Net::HTTP.post( URI("http(s)://HOSTNAME/login/oauth/access_token"), URI.encode_www_form(params), {"Accept" => "application/json"} ) parse_response(result) end get "/" do link = '<a href="http(s)://HOSTNAME/login/oauth/authorize?client_id=<%= CLIENT_ID %>">Login with GitHub</a>' erb link end get "CALLBACK_URL" do code = params["code"] token_data = exchange_code(code) if token_data.key?("access_token") token = token_data["access_token"] render = "Successfully authorized! Got code #{code} and exchanged it for a user access token ending in #{token[-9..-1]}." erb render else render = "Authorized, but unable to exchange code #{code} for token." erb render end end
- A função
-
Opcionalmente, verifique seu progresso:
- No terminal, no diretório em que
app.rb
está armazenado, executeruby app.rb
. Um servidor local do Sinatra deve ser iniciado. - No navegador, navegue até
http://localhost:4567
. Você verá um link com o texto "Faça logon com o GitHub". - Clique no link "Fazer logon com o GitHub".
- Se precisar fazer isso, autorize seu aplicativo.
- A página da URL de retorno de chamada, acessada com um clique no link "Fazer logon com o GitHub" e com a autorização do aplicativo, se solicitado, exibirá um texto semelhante a "Autorizado com sucesso! Código 4acd44861aeda86dacce recebido e trocado por um token de acesso do usuário que termina em 2zU5kQziE".
- No terminal em que o Sinatra está em execução, interrompa o servidor inserindo CTRL+C.
- No terminal, no diretório em que
-
Agora que você tem um token de acesso do usuário, use o token para fazer solicitações de API em nome do usuário. Por exemplo:
Adicione esta função a
app.rb
para obter informações sobre o usuário com o ponto de extremidade/user
da API REST:Ruby def user_info(token) uri = URI("http(s)://HOSTNAME/api/v3/user") result = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http| body = {"access_token" => token}.to_json auth = "Bearer #{token}" headers = {"Accept" => "application/json", "Content-Type" => "application/json", "Authorization" => auth} http.send_request("GET", uri.path, body, headers) end parse_response(result) end
def user_info(token) uri = URI("http(s)://HOSTNAME/api/v3/user") result = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http| body = {"access_token" => token}.to_json auth = "Bearer #{token}" headers = {"Accept" => "application/json", "Content-Type" => "application/json", "Authorization" => auth} http.send_request("GET", uri.path, body, headers) end parse_response(result) end
Atualize o manipulador de retorno de chamada para chamar a função
user_info
e exibir o nome do usuário e o logon do GitHub. Lembre-se de substituirCALLBACK_URL
pela URL de retorno de chamada do seu aplicativo, menos o domínio.Ruby get "CALLBACK_URL" do code = params["code"] token_data = exchange_code(code) if token_data.key?("access_token") token = token_data["access_token"] user_info = user_info(token) handle = user_info["login"] name = user_info["name"] render = "Successfully authorized! Welcome, #{name} (#{handle})." erb render else render = "Authorized, but unable to exchange code #{code} for token." erb render end end
get "CALLBACK_URL" do code = params["code"] token_data = exchange_code(code) if token_data.key?("access_token") token = token_data["access_token"] user_info = user_info(token) handle = user_info["login"] name = user_info["name"] render = "Successfully authorized! Welcome, #{name} (#{handle})." erb render else render = "Authorized, but unable to exchange code #{code} for token." erb render end end
-
Verifique o código em relação ao exemplo de código completo na próxima seção. Teste o código seguindo as etapas descritas na seção "Teste" abaixo do exemplo de código completo.
Exemplo de código completo
Este é o exemplo de código completo descrito na seção anterior.
Substitua CALLBACK_URL
pela URL de retorno de chamada do seu aplicativo, menos o domínio. Por exemplo, se a URL de retorno de chamada for http://localhost:4567/github/callback
, substitua CALLBACK_URL
por /github/callback
.
require "sinatra" require "dotenv/load" require "net/http" require "json" CLIENT_ID = ENV.fetch("CLIENT_ID") CLIENT_SECRET = ENV.fetch("CLIENT_SECRET") def parse_response(response) case response when Net::HTTPOK JSON.parse(response.body) else puts response puts response.body {} end end def exchange_code(code) params = { "client_id" => CLIENT_ID, "client_secret" => CLIENT_SECRET, "code" => code } result = Net::HTTP.post( URI("http(s)://HOSTNAME/login/oauth/access_token"), URI.encode_www_form(params), {"Accept" => "application/json"} ) parse_response(result) end def user_info(token) uri = URI("http(s)://HOSTNAME/api/v3/user") result = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http| body = {"access_token" => token}.to_json auth = "Bearer #{token}" headers = {"Accept" => "application/json", "Content-Type" => "application/json", "Authorization" => auth} http.send_request("GET", uri.path, body, headers) end parse_response(result) end get "/" do link = '<a href="http(s)://HOSTNAME/login/oauth/authorize?client_id=<%= CLIENT_ID %>">Login with GitHub</a>' erb link end get "CALLBACK_URL" do code = params["code"] token_data = exchange_code(code) if token_data.key?("access_token") token = token_data["access_token"] user_info = user_info(token) handle = user_info["login"] name = user_info["name"] render = "Successfully authorized! Welcome, #{name} (#{handle})." erb render else render = "Authorized, but unable to exchange code #{code} for token." erb render end end
require "sinatra"
require "dotenv/load"
require "net/http"
require "json"
CLIENT_ID = ENV.fetch("CLIENT_ID")
CLIENT_SECRET = ENV.fetch("CLIENT_SECRET")
def parse_response(response)
case response
when Net::HTTPOK
JSON.parse(response.body)
else
puts response
puts response.body
{}
end
end
def exchange_code(code)
params = {
"client_id" => CLIENT_ID,
"client_secret" => CLIENT_SECRET,
"code" => code
}
result = Net::HTTP.post(
URI("http(s)://HOSTNAME/login/oauth/access_token"),
URI.encode_www_form(params),
{"Accept" => "application/json"}
)
parse_response(result)
end
def user_info(token)
uri = URI("http(s)://HOSTNAME/api/v3/user")
result = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
body = {"access_token" => token}.to_json
auth = "Bearer #{token}"
headers = {"Accept" => "application/json", "Content-Type" => "application/json", "Authorization" => auth}
http.send_request("GET", uri.path, body, headers)
end
parse_response(result)
end
get "/" do
link = '<a href="http(s)://HOSTNAME/login/oauth/authorize?client_id=<%= CLIENT_ID %>">Login with GitHub</a>'
erb link
end
get "CALLBACK_URL" do
code = params["code"]
token_data = exchange_code(code)
if token_data.key?("access_token")
token = token_data["access_token"]
user_info = user_info(token)
handle = user_info["login"]
name = user_info["name"]
render = "Successfully authorized! Welcome, #{name} (#{handle})."
erb render
else
render = "Authorized, but unable to exchange code #{code} for token."
erb render
end
end
Testando
Este tutorial pressupõe que o código do aplicativo esteja armazenado em um arquivo chamado app.rb
e que você esteja usando a URL padrão para um aplicativo local do Sinatra, http://localhost:4567
.
-
No terminal, no diretório em que
app.rb
está armazenado, executeruby app.rb
. Um servidor local do Sinatra deve ser iniciado. -
No navegador, navegue até
http://localhost:4567
. Você verá um link com o texto "Faça logon com o GitHub". -
Clique no link "Fazer logon com o GitHub".
Caso não tenha autorizado o aplicativo, se você clicar no link, será levado para
http(s)://HOSTNAME/login/oauth/authorize?client_id=CLIENT_ID
, sendo queCLIENT_ID
é a ID do cliente do aplicativo. Essa é uma página do GitHub que solicita aos usuários a autorizar seu aplicativo. Se você clicar no botão para autorizar seu aplicativo, acessará a URL de retorno de chamada do aplicativo.Se você autorizou seu aplicativo anteriormente e a autorização não foi revogada, o prompt de autorização é ignorado e leva você diretamente para a URL de retorno de chamada. Você poderá revogar sua autorização anterior se quiser ver a solicitação de autorização. Para obter mais informações, confira "Revisar e revogar a autorização dos Aplicativos GitHub".
-
A página da URL de retorno de chamada, acessada com um clique no link "Fazer logon com o GitHub" e com a autorização do aplicativo, se solicitado, exibirá um texto semelhante a "Autorizado com sucesso! Bem-vinda, Mona Lisa (octocat)".
-
No terminal em que o Sinatra está em execução, interrompa o servidor inserindo CTRL+C.
Próximas etapas
Armazenar o segredo do cliente com segurança
Você nunca deve divulgar o segredo do cliente do aplicativo. Este tutorial armazenou o segredo do cliente em um arquivo .env
ignorado pelo Git e acessou o valor com ENV.fetch
. Ao implantar seu aplicativo, você deve escolher uma forma segura de armazenar o segredo do cliente e atualizar o código para obter o valor de acordo.
Por exemplo, você pode armazenar o segredo em uma variável de ambiente no servidor em que o aplicativo foi implantado. Use também um serviço de gerenciamento de segredos como o Azure Key Vault.
Atualizar a URL de retorno de chamada para implantação
Este tutorial usou uma URL de retorno de chamada que começa com http://localhost:4567
. No entanto, http://localhost:4567
só estará disponível localmente para o computador quando você iniciar o servidor do Sinatra. Antes de implantar seu aplicativo, você deve atualizar a URL de retorno de chamada para usar a URL de retorno de chamada que você usa em produção. Para obter mais informações sobre como atualizar a URL de retorno de chamada do seu aplicativo, confira "Modificar um registro do Aplicativo GitHub" e "Sobre a URL de retorno de chamada de autorização do usuário".
Processar várias URLs de retorno de chamada
Este tutorial usou uma só URL de retorno de chamada, mas seu aplicativo pode ter até dez URLs de retorno de chamada. Caso você deseje usar várias URLs de retorno de chamada:
- Adicione as outras URLs de retorno de chamada ao aplicativo. Para obter mais informações sobre como adicionar URLs de retorno de chamada, confira "Modificar um registro do Aplicativo GitHub".
- Ao vinculá-la ao
http(s)://HOSTNAME/login/oauth/authorize
, use o parâmetro de consultaredirect_uri
para redirecionar os usuários para a URL de retorno de chamada desejada. Para obter mais informações, confira "Como gerar um token de acesso do usuário para um GitHub App". - No código do aplicativo, processe cada URL de retorno de chamada, semelhante ao bloco de código que começa com
get "CALLBACK_URL" do
.
Especificar parâmetros adicionais
Ao vinculá-la ao http(s)://HOSTNAME/login/oauth/authorize
, você pode transmitir parâmetros de consulta adicionais. Para obter mais informações, confira "Como gerar um token de acesso do usuário para um GitHub App".
Ao contrário de um token OAuth tradicional, o token de acesso do usuário não usa escopos, ou seja, não é possível especificar escopos por meio do parâmetro scope
. Em vez disso, ele usa permissões refinadas. Um token de acesso do usuário só tem permissões que o usuário e o aplicativo têm.
Ajustar o código de acordo com as necessidades do aplicativo
Este tutorial demonstrou como exibir informações sobre o usuário autenticado, mas você pode ajustar esse código para executar outras ações. Lembre-se de atualizar as permissões do aplicativo se o aplicativo precisar de permissões adicionais para as solicitações de API que você deseja fazer. Para obter mais informações, confira "Escolhendo permissões para um Aplicativo GitHub".
Este tutorial armazenou todo o código em um só arquivo, mas o ideal é mover funções e componentes para arquivos separados.
Armazenar tokens com segurança
Este tutorial gera um token de acesso do usuário. A menos que você tenha recusado o vencimento de tokens de acesso do usuário, o token de acesso do usuário vence após oito horas. Você também receberá um token de atualização que pode regenerar um token de acesso do usuário. Para obter mais informações, confira "Atualizar tokens de acesso do usuário".
Se você pretende interagir ainda mais com as APIs do GitHub, armazene o token para uso futuro. Se optar por armazenar o token de acesso do usuário ou atualizar o token, armazene-o com segurança. Você nunca deve divulgar o token.
Para obter mais informações, confira "Práticas recomendadas para criar um aplicativo do GitHub".
Seguir as práticas recomendadas
Você deve ter como objetivo seguir as melhores práticas com seu GitHub App. Para obter mais informações, confira "Práticas recomendadas para criar um aplicativo do GitHub".