# 为用户发现资源

了解如何通过向 REST API 发出经过身份验证的请求，找到您的应用程序能够为用户可靠地访问的仓库和组织。

向 GitHub API 发出经过身份验证的请求时，应用程序通常需要提取当前用户的存储库和组织。 在本指南中，我们将介绍如何可靠地发现这些资源。

若要与 GitHub API 交互，我们将使用 [Octokit.rb](https://github.com/octokit/octokit.rb)。 可以在 [platform-samples](https://github.com/github/platform-samples/tree/master/api/ruby/discovering-resources-for-a-user) 存储库中找到此项目的完整源代码。

## 入门

在开始以下示例之前，应阅读[身份验证基础知识](/zh/enterprise-server@3.22/apps/oauth-apps/building-oauth-apps/authenticating-to-the-rest-api-with-an-oauth-app)指南（如果尚未阅读）。 以下示例假定你 [已注册了一个 OAuth app](/zh/enterprise-server@3.22/apps/oauth-apps/building-oauth-apps/authenticating-to-the-rest-api-with-an-oauth-app#registering-your-app) ， [并且应用程序具有用户的 OAuth 令牌](/zh/enterprise-server@3.22/apps/oauth-apps/building-oauth-apps/authenticating-to-the-rest-api-with-an-oauth-app#making-authenticated-requests)。

## 发现您的应用程序能够为用户访问的仓库

用户除了拥有他们自己的个人仓库之外，可能还是其他用户和组织所拥有仓库上的协作者。 这些是用户具有特权访问权限的存储库：用户具有读取或写入访问权限的专用存储库，或者是具有写入访问权限的公共存储库或内部存储库。

[OAuth 作用域](/zh/enterprise-server@3.22/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps)和[组织应用程序策略](https://developer.github.com/changes/2015-01-19-an-integrators-guide-to-organization-application-policies/)决定了你的应用可以为用户访问其中哪些存储库。 使用下面的工作流程来发现这些仓库。

与往常一样，首先需要 [GitHub 的 Octokit.rb](https://github.com/octokit/octokit.rb) Ruby 库。 然后我们将配置 Octokit.rb，使其为我们自动处理分页。 有关分页的详细信息，请参阅 [在 REST API 中使用分页](/zh/enterprise-server@3.22/rest/using-the-rest-api/using-pagination-in-the-rest-api)。

```ruby
require 'octokit'

Octokit.auto_paginate = true
```

接下来，我们将[为给定用户传递应用程序的 OAuth 标记](/zh/enterprise-server@3.22/apps/oauth-apps/building-oauth-apps/authenticating-to-the-rest-api-with-an-oauth-app#making-authenticated-requests)：

```ruby
# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
# Instead, set and test environment variables, like below.
client = Octokit::Client.new :access_token => ENV["OAUTH_ACCESS_TOKEN"]
```

然后，我们便可以提取[应用程序可以为用户访问的存储库](/zh/enterprise-server@3.22/rest/repos/repos#list-repositories-for-the-authenticated-user)：

```ruby
client.repositories.each do |repository|
  full_name = repository[:full_name]
  has_push_access = repository[:permissions][:push]

  access_type = if has_push_access
                  "write"
                else
                  "read-only"
                end

  puts "User has #{access_type} access to #{full_name}."
end
```

## 发现您的应用程序可以为用户访问的组织

应用程序可以为用户执行各种与组织相关的任务。 若要执行这些任务，应用程序需要具有足够权限的 [OAuth 授权](/zh/enterprise-server@3.22/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps)。 例如，`read:org` 作用域允许你[列出团队](/zh/enterprise-server@3.22/rest/teams/teams#list-teams)，`user` 作用域允许你[公开用户的组织成员身份](/zh/enterprise-server@3.22/rest/orgs/members#set-public-organization-membership-for-the-authenticated-user)。 一旦用户将其中一个或多个权限范围授予您的应用程序，您就可以获取用户所属的组织。

就像我们在发现上述存储库时所做的那样，首先需要 [GitHub 的 Octokit.rb](https://github.com/octokit/octokit.rb) Ruby 库并将其配置为处理分页。 有关分页的详细信息，请参阅 [在 REST API 中使用分页](/zh/enterprise-server@3.22/rest/using-the-rest-api/using-pagination-in-the-rest-api)。

```ruby
require 'octokit'

Octokit.auto_paginate = true
```

接下来，我们将[为给定用户传递应用程序的 OAuth 标记](/zh/enterprise-server@3.22/apps/oauth-apps/building-oauth-apps/authenticating-to-the-rest-api-with-an-oauth-app#making-authenticated-requests)，以初始化 API 客户端：

```ruby
# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!
# Instead, set and test environment variables, like below.
client = Octokit::Client.new :access_token => ENV["OAUTH_ACCESS_TOKEN"]
```

然后，我们可以[列出我们的应用程序可以为用户访问的组织](/zh/enterprise-server@3.22/rest/orgs/orgs#list-organizations-for-the-authenticated-user)：

```ruby
client.organizations.each do |organization|
  puts "User belongs to the #{organization[:login]} organization."
end
```

### 返回用户的所有组织成员资格

如果你从头到尾阅读了文档，你可能注意到一种[允许列出用户的公共组织成员身份的 API 方法](/zh/enterprise-server@3.22/rest/orgs/orgs#list-organizations-for-a-user)。 大多数应用程序应避免使用这种 API 方法。 此方法仅返回用户的公共组织成员身份，而不会返回其私有组织成员身份。

作为应用程序开发者，您通常希望您的应用程序被授权访问用户的所有组织。 上述工作流程恰好能满足您的要求。