如何将自定义信息从 App Engine Authenticator 传递到 Endpoint?

Posted

技术标签:

【中文标题】如何将自定义信息从 App Engine Authenticator 传递到 Endpoint?【英文标题】:How can I pass custom information from an App Engine Authenticator to the Endpoint? 【发布时间】:2015-04-11 07:43:12 【问题描述】:

我在这篇帖子 Google Cloud Endpoints and user's authentication 中引用了 @MinWan 的精彩回答,他在其中描述了一种将自定义标头添加到针对 App Engine 的 Cloud Endpoints 的请求的方法。

很明显,我们可以添加一个自定义标头并为每个我们想要对其进行身份验证的服务(例如 Google、Twitter、Facebook)编写一个身份验证器,其中每个身份验证器读取一个特定的标头并针对该服务进行身份验证。如果令牌有效,服务通常会返回带有电子邮件地址或用户 ID 以及一些额外信息 [A] 的响应,我们从中生成 com.google.api.server.spi.auth.common.User,它稍后作为 com.google.appengine.api.users.User 传递到端点方法。

第一个问题:为什么我们有两个不同的用户实体,例如具有不同命名空间的用户?看起来,这些都不是子类/超类,因此它们可能是在幕后显式转换的。

第二个问题:显式转换的用户实体带来的问题是,没有自定义字段可以放置服务返回的额外信息 [A],即额外信息丢失了。此类额外信息可能有助于将外部服务的 oauth2 用户与本地用户或其他服务返回的 oauth2 用户进行匹配。

任何输入?处理多个身份验证服务的建议方法是什么?

【问题讨论】:

由于似乎没有解决方案,我作为解决方法所做的是通过返回 JSON 而不是字符串来“滥用”com.google.api.server.spi.auth.common.User,稍后我可以将其解包。这样我的身份验证器可以存储其他属性。正如我所说,这不是我问题的答案,只是一个丑陋的解决方法。 这是一个有趣的用例。您应该在 Public Issue Tracker 中为 App Engine 提出功能请求! 刚刚测试过,您绝对可以将 User 子类化以包含您想要的任何私有字段。只需使用类继承多态性从 Authenticator 方法返回该类型的对象,而无需更改方法签名中默认 User 的类型。 非常好的解决方案@Nick。如果您将此作为答案发布,我会给您应得的荣誉。 【参考方案1】:

刚刚经过测试,您绝对可以将 User 子类化以包含您想要的任何私有字段。只需使用类继承多态性从 Authenticator 方法返回该类型的对象,而无需更改方法签名中默认 User 的类型。

import javax.servlet.http.HttpServletRequest;
import com.google.api.server.spi.auth.common.User;
import com.google.api.server.spi.config.Authenticator;

public class BazUser extends User 
        private String secret; // extra piece of data held by this User
        public BazUser(String email) 
                super(email);
                this.secret = "notasecret";
        
        public BazUser (String email, String secret) 
                super (email);
                this.secret = secret;
        


public class BazAuthenticator implements Authenticator 
        public User authenticate(HttpServletRequest req) 
                return new BazUser ("userid@baz.com", "secret");
        

【讨论】:

如何从端点端的用户对象获取额外信息?我正在使用最新的 1.9.32 sdk,我收到以下错误:没有找到适合类型 [simple type, class com.aleskovacic.nearby.backend.models.AuthUser] 的构造函数:无法从 JSON 对象实例化(需要添加/启用类型信息?) 您应该将此作为一个新问题发布,并包括:1. 完整的错误输出,2. 您正在使用的代码,3. 有关 HTTP 请求的详细信息以及这些请求的内容(如果可能)等。所有这些信息对于确定系统上发生的情况都是必要的。计算机是非常复杂的机器,具有大量可能的输出,并且从部分错误消息向后映射以找到根本原因 - 除特殊情况外 - 大部分超出了 99.9% 的程序员的技能范围。 我在这里发布了这个问题:***.com/questions/35351830/… 很伤心,但这只有在传入请求中没有正文时才有效。一旦请求有正文,您就无法编译,因为编译器认为 com.google.api.server.spi.auth.common.User 是来自端点的正文:“多个实体参数。(...) " 嘿@OliverHausler,这似乎不应该发生。也许发布一个带有代码和堆栈跟踪的新问题?【参考方案2】:

在功能上,一切都适用:

import com.google.api.server.spi.auth.common.User;

即使是 gradle:

compile 'com.google.endpoints:endpoints-framework:2.0.0-beta.11'

可以通过包含@SuppressWarnings("ResourceParameter") 来清除IDE 警告,如下所示:

/**
 * Adds a new PmpUser.
 *
 * @param pmpUser  pmpUser object
 */
@SuppressWarnings("ResourceParameter")
@ApiMethod(
        name = "pmpUser.post",
        path = "pmpUser",
        httpMethod = ApiMethod.HttpMethod.POST)
...

【讨论】:

以上是关于如何将自定义信息从 App Engine Authenticator 传递到 Endpoint?的主要内容,如果未能解决你的问题,请参考以下文章

如何将自定义道具从 App 传递到单元格以进行 react-table v7?

Google App Engine 烧瓶 SSL 和 OAuth2 问题

如何将自定义装饰器添加到 FastAPI 路由?

如何从 Python 中的 App Engine 在 Google BigQuery 上创建架构?

如何将数据从 Android 移动设备发送到 Google App Engine 数据存储区?

如何将自定义消息添加到 Firebase Google 身份验证弹出窗口?