【问题标题】:How do I control Token Response Expiry time for google API access如何控制谷歌 API 访问的令牌响应过期时间
【发布时间】:2014-01-07 17:52:44
【问题描述】:

我在将标准的 google 访问令牌有效期延长一小时时遇到问题。 我的代码的一部分是根据 Google 的建议使用GoogleAuthorizationCodeFlow 从用户那里获得授权。这工作正常,并给了我一个 TokenResponse,我坚持在用户未连接的应用程序的其他部分中使用它。

根据 Google 文档,我认为流程中的 "offline" 访问类型将使 TokenResponse 只要用户不撤销它就可以使用。但显然,当我在用户授权后使用此 TokenReponse 时,它​​工作正常,但是当我在一个多小时后使用它时,我收到了 Google 发回的“无效凭据”。

这是用户授权后创建 TokenResponse 的代码:

private HttpTransport HTTP_TRANSPORT;
private JacksonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

private static GoogleAuthorizationCodeFlow flow;

@PostConstruct
public void init() {
    try {

        HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
    } catch (GeneralSecurityException | IOException e) {
        logger.info(String.format("Raised Exception while getting GoogleNetHttpTransport : %s", e.getMessage()));
        e.printStackTrace();
    }
    flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY, APP_ID, APP_SECRET,
            Collections.singleton(CalendarScopes.CALENDAR_READONLY)).setAccessType("offline").build();
}
@RequestMapping(value = Uris.GOOGLERD)
public ModelAndView googleCallBack(HttpServletRequest request, @RequestParam(value = "state", required = false) String state,
        @RequestParam(value = "code", required = false) String code,
        @RequestParam(value = "error", required = false) String error, Model model) {
    DynSubscriber dynSubscriber = (DynSubscriber) request.getSession().getAttribute("dynSubscriber");
    ModelAndView toReturn = new ModelAndView("confirmation");
    toReturn.addObject("buttonLabel", "Accueil");

    try {

        AuthorizationCodeTokenRequest tokenRequest = flow.newTokenRequest(code);
        TokenResponse tr = tokenRequest.setRedirectUri(request.getRequestURL().toString()).execute();


        // Json Conversion of Token Response for future use
        StringWriter jsonTrWriter = new StringWriter();
        JsonGenerator generator = JSON_FACTORY.createJsonGenerator(jsonTrWriter);
        generator.serialize(tr);
        generator.flush();
        generator.close();


        //Persists google access info 
        dynSubOp.setSPConnexionInfo(dynSubscriber, jsonTrWriter.toString(), DynServiceProviderType.GOOGLECAL);
        toReturn.addObject("message","Agenda Google autorisé");

    } catch (IOException | DynServicesException e) {
        logger.error(String.format("Exception raised in googleCallBack for subscriber %s : %s", dynSubscriber.buildFullName(), e.getMessage()),e);
        toReturn.addObject("message", "Problème lors du processus d'autorisation google");
    }

    return toReturn;
}
}

这里是使用这个 TokenReponse 的离线代码:

private com.google.api.services.calendar.Calendar calendarConnection;


public DynGoogleCalendarRetriever(String subid, String connectionInformation)
        throws CalendarConnectionNotAuthorizedException {


    TokenResponse tr;
    try {
        HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
        tr = JSON_FACTORY.fromString(connectionInformation, TokenResponse.class);

        Credential c = new GoogleCredential().setFromTokenResponse(tr);
        calendarConnection = new com.google.api.services.calendar.Calendar.Builder(HTTP_TRANSPORT, JSON_FACTORY, c)
                .build();
    } catch (IOException | GeneralSecurityException e) {
        logger.error(String.format("Failure creating the credentials for subscriber id %s", subid), e);
        throw new CalendarConnectionNotAuthorizedException(String.format(
                "Failure creating the credentials for subscriber id %s", subid), e);
    }


}

【问题讨论】:

    标签: google-api google-oauth google-oauth-java-client


    【解决方案1】:

    看来this other SO question 已经回答了这个问题。 要获得启用我想要的刷新令牌,我需要使用 approval_prompt=force 参数 (builder.setApprovalPrompt("force")) 构建流程

    根据评论,这需要在流程初始化中完成的离线访问。

    然而,补充:尽管我从谷歌文档(可能是旧版本)复制并粘贴了它,但我的问题中的离线代码不起作用。 Credential 需要使用它的 Builder 对象。

    这是功能齐全的离线代码:

        TokenResponse tr;
        try {
            HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
            tr = JSON_FACTORY.fromString(connectionInformation, TokenResponse.class);
    
            Credential c = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT).setJsonFactory(JSON_FACTORY)
                    .setClientSecrets(APP_ID, APP_SECRET).build().setFromTokenResponse(tr);
    
            calendarConnection = new com.google.api.services.calendar.Calendar.Builder(HTTP_TRANSPORT, JSON_FACTORY, c)
                    .build();
        } catch (IOException | GeneralSecurityException e) {
            logger.error(String.format("Failure creating the credentials for subscriber id %s", subid), e);
            throw new CalendarConnectionNotAuthorizedException(String.format(
                    "Failure creating the credentials for subscriber id %s", subid), e);
        }
    

    【讨论】:

    • 引用不正确。您可能出于其他原因需要强制批准,但这并不影响您是否赢得刷新令牌。要获取刷新令牌,您需要请求 离线 访问权限。
    猜你喜欢
    • 2012-05-10
    • 1970-01-01
    • 1970-01-01
    • 2014-10-17
    • 2020-11-27
    • 2012-11-30
    • 1970-01-01
    • 2013-07-20
    相关资源
    最近更新 更多