[英]How do I protect my API that was built using Google Cloud Endpoints?
API 是移动应用程序的后端。 我不需要用户身份验证。 我只需要一种方法来保护对这个 API 的访问。 目前,我的后端已公开。
文档好像只讲了用户认证和授权,这里不是我需要的。 我只需要确保只有我的移动应用程序可以与此后端通信,而不能与其他任何人通信。
是的,您可以这样做:使用身份验证来保护您的端点,而无需进行用户身份验证。
我发现这种做法没有得到很好的记录,我自己也没有真正做到过,但我打算这样做,所以当我看到在一些 IO13 视频中讨论它时,我注意到了(我认为这就是我的地方看到了):
以下是我对所涉及内容的理解:
您将这些客户端 ID 添加到端点的可接受 ID 列表中。 您将向端点添加 User 参数,但由于未指定用户,因此它将为空。
@ApiMethod(
name = "sendInfo",
clientIds = { Config.WEB_CLIENT_ID, Config.MY_APP_CLIENT_ID, Config.MY_DEBUG_CLIENT_ID },
audiences = { Config.WEB_CLIENT_ID }
// Yes, you specify a 'web' ID even if this isn't a Web client.
)
public void sendInfo(User user, Info greeting) {
关于上述内容,有一些不错的文档,这里是: https : //developers.google.com/appengine/docs/java/endpoints/auth
您的客户端应用程序将在制定端点服务调用时指定这些客户端 ID。 所有 OATH 详细信息都将在您的客户端设备的幕后得到处理,以便您的客户端 ID 被转换为身份验证令牌。
HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = new JacksonFactory();
GoogleAccountCredential credential = GoogleAccountCredential.usingAudience( ctx, Config.WEB_CLIENT_ID );
//credential.setSelectedAccountName( user ); // not specify a user
Myendpoint.Builder builder = new Myendpoint.Builder( transport, jsonFactory, credential );
这个客户端代码只是我最好的猜测 - 抱歉。 如果其他人有关于客户端代码应该是什么样子的参考,那么我也会感兴趣。
很抱歉,Google 没有为您的问题提供解决方案(这也是我的问题)。 您可以使用他们的 API 密钥机制(请参阅https://developers.google.com/console/help/new/#usingkeys ),但 Google 自己的 API 浏览器提供的此策略存在巨大漏洞(请参阅https://developers.google.com/console/help/new/#usingkeys developer.google.com/apis-explorer/#p/ ),这是一个很好的测试 API 的开发工具,但公开了所有 Cloud Endpoint API,而不仅仅是 Google 的服务 API。 这意味着任何知道您项目名称的人都可以在闲暇时浏览和调用您的 API,因为 API Explorer 绕过了 API 密钥安全。 我找到了一种解决方法(基于 bossylobster 对这篇文章的精彩回应: Simple Access API (Developer Key) with Google Cloud Endpoint (Python) ),即传递一个请求字段,该字段不属于您的客户端 API 中的消息请求定义的一部分,然后在您的 API 服务器中读取它。 如果您没有找到未记录的字段,则会引发未经授权的异常。 这将堵塞 API 资源管理器创建的漏洞。 在 iOS(我用于我的应用程序)中,您向每个请求类(由 Google 的 API 生成器工具创建的类)添加一个属性,如下所示:
@property (copy) NSString *hiddenProperty;
并将其值设置为您选择的键。 在您的服务器代码(在我的例子中是 python)中,您检查它是否存在,如果您没有看到它或者它没有设置为您的服务器和客户端将同意的值,则检查它的存在和 barf:
mykey,keytype = request.get_unrecognized_field_info('hiddenProperty')
if mykey != 'my_supersecret_key':
raise endpoints.UnauthorizedException('No, you dont!')
希望这能让你走上正轨
该文档仅供客户使用。 我需要的是有关如何在服务器端提供服务帐户功能的文档。
这可能意味着一些不同的事情,但我想解决我认为问题所问的问题。 如果您只想让您的服务帐户访问您的服务,那么您只需将服务帐户的 clientId 添加到您的 @Api/@ApiMethod 注释中,构建一个 GoogleCredential,然后像往常一样调用您的服务。 具体来说...
在 google 开发者控制台中,创建一个新的服务帐户。 这将创建一个自动下载的 .p12 文件。 客户端在您链接到的文档中使用它。 如果您不能保证 .p12 的安全,那么这并不比密码安全多少。 我猜这就是 Cloud Endpoints 文档中没有明确规定的原因。
您将 google 开发者控制台中显示的 CLIENT ID 添加到 @Api 或 @ApiMethod 注释中的 clientIds
import com.google.appengine.api.users.User
@ApiMethod(name = "doIt", scopes = { Constants.EMAIL_SCOPE },
clientIds = { "12345678901-12acg1ez8lf51spfl06lznd1dsasdfj.apps.googleusercontent.com" })
public void doIt(User user){ //by convention, add User parameter to existing params
// if no client id is passed or the oauth2 token doesn't
// match your clientId then user will be null and the dev server
// will print a warning message like this:
// WARNING: getCurrentUser: clientId 1234654321.apps.googleusercontent.com not allowed
//..
}
您以与使用不安全版本相同的方式构建客户端,唯一的区别是您创建了一个 GoogleCredential 对象以传递给您的服务的 MyService.Builder。
HttpTransport httpTransport = new NetHttpTransport(); // or build AndroidHttpClient on Android however you wish
JsonFactory jsonFactory = new JacksonFactory();
// assuming you put the .p12 for your service acccount
// (from the developer's console) on the classpath;
// when you deploy you'll have to figure out where you are really
// going to put this and load it in the appropriate manner
URL url = getClass().class.getResource("/YOURAPP-b12345677654.p12");
File p12file = new File(url.toURI());
GoogleCredential.Builder credentialBuilder = new GoogleCredential.Builder();
credentialBuilder.setTransport(httpTransport);
credentialBuilder.setJsonFactory(jsonFactory);
//NOTE: use service account EMAIL (not client id)
credentialBuilder.setServiceAccountId("12345678901-12acg1ez8lf51spfl06lznd1dsasdfj@developer.gserviceaccount.com"); credentialBuilder.setServiceAccountScopes(Collections.singleton("https://www.googleapis.com/auth/userinfo.email"));
credentialBuilder.setServiceAccountPrivateKeyFromP12File(p12file);
GoogleCredential credential = credentialBuilder.build();
现在以与不安全版本相同的方式调用您生成的客户端,除了构建器将我们上面的谷歌凭据作为最后一个参数
MyService.Builder builder = new MyService.Builder(httpTransport, jsonFactory, credential);
builder.setApplicationName("APP NAME");
builder.setRootUrl("http://localhost:8080/_ah/api");
final MyService service = builder.build();
// invoke service same as unsecured version
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.