GoogleIdTokenVerifier 不返回名称、图片等

Posted

技术标签:

【中文标题】GoogleIdTokenVerifier 不返回名称、图片等【英文标题】:GoogleIdTokenVerifier does not return name, picture, etc 【发布时间】:2017-04-17 16:44:58 【问题描述】:

我们正在使用 goole-client-api 库从我们的后端验证 Google 帐户。此实现使用 App Engine 和 DataStore 在 Google Cloud Platform (GCP) 上运行。

到目前为止,我们看到的是 GoogleIdTokenVerifier 可以工作,但只返回电子邮件和 uid 以及令牌签名。

当针对我们的 servlet 但不通过我们的 App Engine Endpoint 运行时,使用的令牌和 uid 会返回所有配置文件信息。

这里是使用的代码:

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
import com.google.api.client.extensions.appengine.http.UrlFetchTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collections;
import java.util.logging.Logger;

public class GoogleVerifier implements TokenVerifier 



final Logger logger = Logger.getLogger(GoogleVerifier.class.getName());

    private static GoogleVerifier instance = null;

    private String privAppId;
    private UrlFetchTransport httpTransport;    //library required to run on GCP
    private JsonFactory jsonFactory;

    private GoogleVerifier() 
    


    private static GoogleVerifier getInstance() 
        if (instance == null) 
            instance = new GoogleVerifier();
        

        return instance;
    


    public static void setAppId(String appId) 
        getInstance().setPrivAppId(appId);
        getInstance().setHttpTransport(new UrlFetchTransport());
        getInstance().setJsonFactory(new JacksonFactory());
    

    public static String[] verify(String token, String uid) 
        return getInstance().verifyPrivate(token, uid);
    

    public String[] verifyPrivate(String token, String uid) 
        @SuppressWarnings("unused")
        GoogleCredential credential = new GoogleCredential().setAccessToken(token);

        GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(httpTransport, jsonFactory)
                .setAudience(Collections.singletonList(privAppId))
                .build();

        String[] payloadInfo = new String[5];

        try 
            GoogleIdToken idToken = verifier.verify(token);

            if (idToken != null) 
                GoogleIdToken.Payload payload = idToken.getPayload();

                if (payload.getSubject().equals(uid)) 
                    logger.info("Matching google id: " + uid);

                    payloadInfo[0] = payload.getSubject();
                    payloadInfo[1] = payload.get("given_name").toString();
                    payloadInfo[2] = payload.get("family_name").toString();
                    payloadInfo[3] = payload.get("picture").toString();
                    payloadInfo[4] = payload.getEmail();

                    return payloadInfo;
                 else 
                    logger.info("Mismatching google id: " + uid);
                    return payloadInfo;
                
            
        
        catch (Exception e) 
            e.printStackTrace();
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            logger.warning(sw.toString());

            return payloadInfo;
        

        return payloadInfo;
    

    private void setPrivAppId(String appId) 
        this.privAppId = appId;
    

    private void setHttpTransport(UrlFetchTransport httpTransport) 
        this.httpTransport = httpTransport;
    

    private void setJsonFactory(JsonFactory jsonFactory) 
        this.jsonFactory = jsonFactory;
    

这是我们的 App Engine 端点:

@ApiMethod(name = "loginSocial", path = "loginSocial", httpMethod = HttpMethod.PUT)
public Response loginSocial(@Named("token") String token,
                            @Named("uid") String uid,
                            @Named("socialWebSite") SOCIALWEBSITE socialWebSite,
                            HttpServletRequest request) throws DatabaseException, IOException 

    Response response = new Response();

    //make sure parameters and not null or empty
    if (token != null && uid != null && socialWebSite != null &&
        !token.trim().isEmpty() && !uid.trim().isEmpty())

        String [] userInfo = new String[5];

        //validate token and retrieve info first
        if (socialWebSite.equals(SOCIALWEBSITE.GOOGLE))
            GoogleVerifier.setAppId(APP_ID);
            userInfo = GoogleVerifier.verify(token, uid);           
        else if(socialWebSite.equals(APP_ID);
            userInfo = FacebookVerifier.verify(token, uid);             
        
    

谢谢!

【问题讨论】:

用户认证需要哪些范围? 简答:电子邮件和个人资料。 长答案:用户当前连接到通过 servlet 的网页。这个 servlet 能够检索一些东西:电子邮件、配置文件、uid、令牌等...在尝试使用相同的 APP ID、uid 和令牌通过 App Engine 检索相同的信息时,这些方法不会返回配置文件信息。 我把事情颠倒了——对不起。在您的 EP 中,您应该在进行身份验证时添加配置文件范围。 【参考方案1】:

我最终使用了一个更简单且提供相同信息的不同库。

https://***.com/questions/22516693

【讨论】:

以上是关于GoogleIdTokenVerifier 不返回名称、图片等的主要内容,如果未能解决你的问题,请参考以下文章

Android:GoogleIdTokenVerifier.Builder中的transport和jsonFactory是什么?

如何正确实例化 GoogleIdTokenVerifier / .setAudience() 做啥?

Google 登录 GoogleIdToken 后端验证突然失败

Mongoose User.findOne 既不返回错误也不返回成功

移动端 点击返回按钮页面不刷新

vue实现返回上一页面,页面停留在原来位置,不刷新