如何关联Google App Engine Endpoints与前端的不同用户ID?
关联Google App Engine Endpoints与Web前端的用户ID
这个问题的核心在于两个User类对应的是完全不同的ID体系:
com.google.api.server.spi.auth.common.User.getUserId()返回的是Google账户的全局唯一ID(也就是你看到的Google+个人主页ID),这个ID在所有Google服务中固定不变,和具体应用无关。com.google.appengine.api.users.User.getUserId()返回的是App Engine应用专属的本地用户ID,GAE会为每个用户在当前应用内生成这个唯一标识,同一个用户在不同GAE应用里的这个ID都不一样,和全局ID没有直接关联。
下面是几种无需依赖邮箱的关联方案,按推荐优先级排序:
1. 统一使用全局Google ID作为用户标识
这是最简洁的方案,直接抛弃GAE的本地ID,在两端都用全局ID来标识用户:
- Endpoints端:直接使用
com.google.api.server.spi.auth.common.User.getUserId()拿到的全局ID作为用户主键存储数据。 - Web前端(JSP)端:
- 配置你的GAE Web应用使用OAuth2登录(代替默认的Google Accounts登录),确保登录时请求
openid和profilescope。 - 登录成功后,通过Google OAuth2的
userinfo接口(或使用Google API Client Library)获取用户的sub字段值——这个值就是全局ID,和Endpoints返回的getUserId()结果完全一致。 - 用这个全局ID作为用户的唯一标识存储数据,这样两端的用户身份就天然统一了。
- 配置你的GAE Web应用使用OAuth2登录(代替默认的Google Accounts登录),确保登录时请求
2. 在Endpoints中获取GAE本地ID并关联
如果你需要保留GAE本地ID的使用,可以通过配置让Endpoints能识别GAE的用户身份,进而拿到本地ID:
- 首先,确保你的Endpoints API使用的OAuth2客户端ID是属于你的GAE应用的(在Google Cloud Console中创建"Web application"类型的客户端ID,授权回调URL指向你的GAE域名)。
- 在你的Endpoints类的
@Api注解中添加认证配置:@Api( name = "yourApiName", auth = @ApiAuth(allowCookieAuth = true) ) - 配置完成后,再次调用
UserServiceFactory.getUserService().getCurrentUser()就能拿到有效的com.google.appengine.api.users.User对象,获取本地ID。 - 最后在你的数据存储中创建一个关联表,将全局ID(Endpoints的
getUserId())和GAE本地ID绑定,后续就可以通过这个表在两端关联用户。
3. 在Web前端获取全局ID并关联到GAE本地ID
如果你的Web端已经在使用GAE本地ID,可以在Web端主动获取全局ID并建立关联:
- 当用户通过GAE的
UserService登录后,在JSP中使用Google API Client Library发起请求,获取用户的全局ID(sub字段)。这里不需要手动处理Authorization头,因为GAE的会话已经包含了用户的认证信息,Client Library会自动处理。 - 在数据存储中存储GAE本地ID和全局ID的映射关系,之后Endpoints端可以通过全局ID查询到对应的GAE本地ID,反之亦然。
关于你之前的尝试
你在Endpoints中调用UserService.getCurrentUser()返回null,是因为缺少两个关键配置:
- Endpoints的OAuth2客户端ID和Web应用的客户端ID不匹配,导致GAE无法将Endpoints的认证用户映射到本地用户。
@Api注解没有启用allowCookieAuth,Endpoints默认不会识别GAE的会话认证信息。
内容的提问来源于stack exchange,提问作者BenTaylor
相关产品推荐
相关产品推荐

