代码之家  ›  专栏  ›  技术社区  ›  Dhanu K

如何在过期后自动更新Gmail凭据

  •  1
  • Dhanu K  · 技术社区  · 6 年前

    我正在使用Gmail Java API, API工作正常,当我们授予google帐户访问权限时,凭据存储在本地,但在凭据过期60分钟后,它不会自动更新凭据。使用我的代码进行调试时,它会在以下位置停止

    凭据凭据=应用程序。授权(“用户”);

    如何在凭据过期后处理,它只有在调用oauth2身份验证后才能再次工作。是否可以自动刷新此功能 这是我的代码块

    /**
         * Creates an authorized Credential object.
         * @return an authorized Credential object.
         * @throws IOException
         */
        public static Credential authorize() throws IOException {
            // Load client secrets.
            InputStream in =
                    Quickstart.class.getResourceAsStream("/client_secret.json");
            GoogleClientSecrets clientSecrets =
                    GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
            HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
            HttpSession session = request.getSession();
            User user =  (User) session.getAttribute("USER");
            java.io.File DATA_STORE_DIR = new java.io.File(
                    //System.getProperty("user.home"), ".credentials/"+user.getUserAccountId()+"/gmail-java-quickstart");
                    Common.commonPath+File.separator+"client_secrets"+File.separator+user.getUserAccountId()+"/gmail-java-quickstart");
            DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
            // Build flow and trigger user authorization request.
            GoogleAuthorizationCodeFlow flow =
                    new GoogleAuthorizationCodeFlow.Builder(
                            HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
                            .setDataStoreFactory(DATA_STORE_FACTORY)
                            .setAccessType("offline")
                            .build();
            System.out.println("*************getApprovalPrompt:"+flow.getApprovalPrompt());
            AuthorizationCodeInstalledApp app = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()){
                protected void onAuthorization(AuthorizationCodeRequestUrl authorizationUrl) throws java.io.IOException {
                    //System.out.println("authorizationUrl:"+authorizationUrl);
                }
            };
            Credential credential = app.authorize("user");
            //System.out.println("*************AUTH_KKEY:"+credential.getAccessToken());
            //System.out.println("Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
            return credential;
        }
    
        /**
         * Build and return an authorized Gmail client service.
         * @return an authorized Gmail client service
         * @throws IOException
         */
        public static Gmail getGmailService() throws IOException {
            Credential credential = authorize();
            return new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
                    .setApplicationName(APPLICATION_NAME)
                    .build();
        }
    
        public List<Message> listMessagesWithLabels(List<String> labelIds,StringBuilder paginationtokenBuilder,Long maxResults) throws IOException {
            List<Message> messages = new ArrayList<Message>();
            try {
                Gmail service = getGmailService();
                // some logic bla bla
            }catch(Exception ex){
                ex.printStackTrace();
                return messages;
            }
        }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Mohan Kanakala    6 年前

    Hay,我也遇到了同样的问题,但在API方面运气不佳。我有一些解决问题的方法,看看是否有用。

    当令牌过期时,API会发出异常(在某些情况下是超时)。这里可以手动刷新令牌(可能带有catch块)。随后的请求将继续使用由前一个请求刷新的更新令牌。下面的代码段。

    例外情况下:

    try {
        response1 = Quickstart.getGmailService().users().messages().list(userId).setLabelIds(labelIds).execute();       
        return response1.getResultSizeEstimate();
    } catch (com.google.api.client.auth.oauth2.TokenResponseException e) {
        e.printStackTrace();
        FileUtils.deleteDirectory(new File(CLIENT_SECRET_PATH+File.separator+"client_secrets"));
        response.sendRedirect("/dashboard"); // redirect to your oauth request URI
    } catch (IOException e) {
        e.printStackTrace();
    }
    

    如果超时(UI):

    $.ajax({
        url:"listGmailLabels", // Request that is hitting Gmail API
        type:"POST",
        success:function(data){
            // Success logic goes here
        },
        complete:function(event){
            if(event.status == 504){
                alert('Token expired! Getting a new refresh token.');
                $.ajax({
                    url:"clearClientSecret", // service call to cleanup the expired token
                    success:function(){
                        window.location.reload();
                    }
                })
            }
        }
     }); 
    

    清理过期令牌的服务:

    @RequestMapping(value="/clearClientSecret",method= {RequestMethod.POST,RequestMethod.GET})
        public void clearClientSecret(HttpServletRequest request,HttpServletResponse response) {
            try {
                String path=CLIENT_SECRET_PATH+File.separator+"client_secrets";
                FileUtils.deleteDirectory(new File(path));
                response.sendRedirect("/dashboard");// redirect to your oauth request URI
            } catch (IOException e1) {
                e1.printStackTrace();
            }
    
        }
    

    我知道这可能不是一个合适的解决方案,但这正是我所尝试的解决方案,所以请让我们所有人都知道是否有什么可以让它变得更好。