【问题标题】:Refresh token and reuse this token to get new access token java刷新令牌并重用此令牌以获取新的访问令牌 java
【发布时间】:2016-11-23 04:10:06
【问题描述】:

如何从首次授权码中获取刷新令牌和访问令牌?而且,如何重用此刷新令牌来获取新的访问令牌以使用 Java API 上传到 Google Drive?这不是一个网络应用程序。它在 Java Swing 代码中。

【问题讨论】:

    标签: google-drive-api


    【解决方案1】:

    我们可以通过以下代码重复使用刷新令牌来获取新的访问令牌

    public class OAuthRefreshToken implements CredentialRefreshListener  {
    
        public static GoogleCredential getAccessTokenFromRefreshToken( String refreshToken, HttpTransport transport, com.google.api.client.json.JsonFactory jsonFactory, String CLIENT_ID, String CLIENT_SECRET) throws IOException
        {
            GoogleCredential.Builder credentialBuilder = new GoogleCredential.Builder()
            .setTransport(transport).setJsonFactory(jsonFactory)
            .setClientSecrets(CLIENT_ID, CLIENT_SECRET);
            credentialBuilder.addRefreshListener(new OAuthRefreshToken());
    
            GoogleCredential credential = credentialBuilder.build();
            credential.setRefreshToken(refreshToken);
            credential.refreshToken();
            return credential;
        }
    
        @Override
        public void onTokenErrorResponse(Credential arg0, TokenErrorResponse arg1)
                throws IOException {
            // TODO Auto-generated method stub
            System.out.println("Error occured !");
            System.out.println(arg1.getError());
        }
    
        @Override
        public void onTokenResponse(Credential arg0, TokenResponse arg1)
                throws IOException {
            // TODO Auto-generated method stub
            System.out.println(arg0.getAccessToken());
            System.out.println(arg0.getRefreshToken());
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      这是我最近根据 Google Drive 文档中的基本示例和一些实验编写的解决方案: IApiKey 包含静态字符串 CLIENT_ID,依此类推。 ITokenPersistence 是一个允许加载和保存令牌(作为字符串)的接口。它将持久性机制(我使用 Preferences 用于 Eclipse e4 RCP 应用程序)与 Uploader 分离。这可以像将令牌存储在文件中一样简单。IAthorizationManager 是一个接口,用于让用户授予访问权限并输入代码以创建刷新令牌。我实现了一个对话框,其中包含一个用于授予访问权限的浏览器小部件和一个用于复制和粘贴代码的文本框。自定义异常GoogleDriveException 对其余代码隐藏了 API 类。

      public final class Uploader implements IApiKey {
      
          public static final String TEXT_PLAIN = "text/plain";
      
          private final ITokenPersistence tokenManager;
          private final IAuthorizationManager auth;
      
          public Uploader(final ITokenPersistence tm, final IAuthorizationManager am) {
              this.tokenManager = tm;
              this.auth = am;
          }
      
          private GoogleCredential createCredentialWithRefreshToken(
                  final HttpTransport transport,
                  final JsonFactory jsonFactory,
                  final String clientId,
                  final String clientSecret,
                  final TokenResponse tokenResponse) {
              return new GoogleCredential.Builder().setTransport(transport)
                      .setJsonFactory(jsonFactory)
                      .setClientSecrets(clientId, clientSecret)
                      .build()
                      .setFromTokenResponse(tokenResponse);
          }
      
          /**
           * Upload the given file to Google Drive.
           * <P>
           * The name in Google Drive will be the same as the file name.
           * @param fileContent a file of type text/plain
           * @param description a description for the file in Google Drive
           * @return Answer the ID of the uploaded file in Google Drive.
           *         Answer <code>null</code> if the upload failed.
           * @throws IOException
           * @throws {@link GoogleDriveException} when a <code>TokenResponseException</code> had been
           *         intercepted while inserting (uploading) the file.
           */
          public String upload(final java.io.File fileContent, final String description) throws IOException, GoogleDriveException {
              HttpTransport httpTransport = new NetHttpTransport();
              JsonFactory jsonFactory = new JacksonFactory();
      
              // If we do not already have a refresh token a flow is created to get a refresh token.
              // To get the token the user has to visit a web site and enter the code afterwards
              // The refresh token is saved and may be reused.
              final GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
                      httpTransport,
                      jsonFactory,
                      CLIENT_ID,
                      CLIENT_SECRET,
                      Arrays.asList(DriveScopes.DRIVE))
              .setAccessType("offline")
              .setApprovalPrompt("auto").build();
      
              final String url = flow.newAuthorizationUrl().setRedirectUri(REDIRECT_URI).build();
              final String refreshToken = this.tokenManager.loadRefreshToken();
      
              GoogleCredential credential = null;
              if( refreshToken == null ) {
                  // no token available: get one
                  String code = this.auth.authorize(url);
                  GoogleTokenResponse response = flow.newTokenRequest(code).setRedirectUri(REDIRECT_URI).execute();
                  this.tokenManager.saveRefreshToken(response.getRefreshToken());
                  credential = this.createCredentialWithRefreshToken(httpTransport, jsonFactory, CLIENT_ID, CLIENT_SECRET, response);
              }
              else {
                  // we have a token, if it is expired or revoked by the user the service call (see below) may fail
                  credential = new GoogleCredential.Builder()
                  .setJsonFactory(jsonFactory)
                  .setTransport(httpTransport)
                  .setClientSecrets(CLIENT_ID, CLIENT_SECRET)
                  .build();
                  credential.setRefreshToken(refreshToken);
              }
      
              //Create a new authorized API client
              final Drive service = new Drive.Builder(httpTransport, jsonFactory, credential)
              .setApplicationName(APP_NAME)
              .build();
      
              //Insert a file
              final File body = new File();
              body.setTitle(fileContent.getName());
              body.setDescription(description);
              body.setMimeType(TEXT_PLAIN);
              final FileContent mediaContent = new FileContent(TEXT_PLAIN, fileContent);
      
              try {
                  final File file = service.files().insert(body, mediaContent).execute();
                  return ( file != null ) ? file.getId() : null;
              } catch (TokenResponseException e) {
                  e.printStackTrace();
                  throw new GoogleDriveException(e.getDetails().getErrorDescription(), e.getCause());
              }
          }
      

      }

      【讨论】:

        猜你喜欢
        • 2015-07-19
        • 2022-01-23
        • 2017-03-22
        • 1970-01-01
        • 2016-09-28
        • 2015-11-26
        • 2019-06-29
        • 2020-02-26
        • 2013-08-23
        相关资源
        最近更新 更多