【问题标题】:AWS Cognito and S3AWS Cognito 和 S3
【发布时间】:2016-08-28 22:24:08
【问题描述】:

我正在开发 Android 应用程序,用户可以在其中从 Amazon S3 上传和下载文件。我已经为我的应用程序开发了身份验证。目前,每当用户想要上传少量文件时,对于每个文件用户都可以通过 ping 我的后端来获得IdentityIDToken

我有几个问题

  1. 我如何知道令牌是否过期?

  2. AWS API 是否保存令牌和身份本身?如果是,如何找回?

  3. 在我的项目中使用IdentityId 和令牌的最佳方式是什么?为每个文件调用后端以获取令牌?或者当用户想要上传一堆(选定的)文件时调用一次?或者如果令牌未过期,保存令牌并重新使用它?

代码:

Auth.java:

public class Auth extends AWSAbstractCognitoDeveloperIdentityProvider {



private Context ctx;
public Auth(String accountId, String identityPoolId, Regions region,Context ctx) {
    super(accountId, identityPoolId, region);
      this.ctx=ctx;

}

@Override
public String getProviderName() {
   return "cognito-identity.amazonaws.com";

}

@Override
public String refresh() {
    setToken(null);

    if (getProviderName() != null &&
            !this.loginsMap.isEmpty() &&
            this.loginsMap.containsKey(getProviderName())&& internetchek.connectGoogle()) {

        Log.d("Refreshing..","Loading..");
        Idtoken();

        update(identityId, token);

        return token;



    } else {

        this.getIdentityId();
        return null;
    }

}
@Override
public String getToken() {
    return token;
}

public void Idtoken(){



    String serverurl = constants.IP_ADDRESS_CREDENTIALS;
    try {
        save s = new save(this.ctx, constants.USER_DETAILS);
        String phonenumber = s.read(constants.PHONE_NUMBER);

        if (phonenumber != null) {


            URL url = new URL(serverurl);
            HttpURLConnection http = (HttpURLConnection) url.openConnection();
            http.setRequestMethod("POST");
            http.setDoInput(true);
            http.setDoOutput(true);

            OutputStream OS = http.getOutputStream();
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(OS, "UTF-8"));
            String data = URLEncoder.encode("number", "UTF-8") + "=" + URLEncoder.encode(phonenumber, "UTF-8");
            bufferedWriter.write(data);
            bufferedWriter.flush();
            bufferedWriter.close();
            OS.close();
            InputStream IS = http.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(IS, "iso-8859-1"));
            String line = "";
            String response="";

            while ((line= bufferedReader.readLine()) != null) {
                response = response+line;

            }
            bufferedReader.close();
            IS.close();
            http.disconnect();

            response = response.replaceAll("\\s+", "");

            Log.d("RESPONCE", response);

            String[] splitter = response.split("==");
            if (splitter[0] != null) {

                if (splitter[1] != null) {

                    identityId = splitter[0];
                    token = splitter[1];

                }

            }
        }
            Log.d("IDENTITYID",identityId);
            Log.d("TOKEN",token);

        }catch(MalformedURLException e){
            e.printStackTrace();
        }catch(UnknownHostException e)
        {
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        }

}}

上传文件

private class Uploadfile extends AsyncTask<Void,Void,Void>{

    Context ctx;
    String remotepath;
    File file;
    ProgressBar progressBar;

    private Uploadfile(Context ctx,File file,String remotepath,ProgressBar progressBar){
        this.ctx =ctx;
        this.file=file;
        this.remotepath=remotepath;
        this.progressBar =progressBar;
    }
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(Void... params) {
        if(!internetchek.isNetworkAvailable(this.ctx)||!internetchek.connectGoogle()){
            Log.d("NETWORK","TRUE");
        }else {
            Auth developerProvider = new Auth(
                    null,
                    "ap-northeast-1:a871fa5fxxxxxxxxxxxxx1437244",
                    Regions.AP_NORTHEAST_1, this.ctx);
            CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
                    this.ctx.getApplicationContext(),
                    developerProvider,
                    Regions.AP_NORTHEAST_1);


            HashMap<String, String> loginsMap = new HashMap<String, String>();
            loginsMap.put("cognito-identity.amazonaws.com", credentialsProvider.getToken());
            credentialsProvider.setLogins(loginsMap);
            credentialsProvider.refresh();

            ClientConfiguration configuration = new ClientConfiguration();
            configuration.setProtocol(Protocol.HTTP);
            configuration.setSocketTimeout(5 * 10000);
            configuration.setConnectionTimeout(5 * 10000);
            configuration.setMaxErrorRetry(3);
            configuration.setMaxConnections(100);

            if (sS3Client == null) {

                sS3Client = new AmazonS3Client(credentialsProvider, configuration);

            }
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);

        if(sS3Client!=null){

            sTransferUtility = new TransferUtility(sS3Client, this.ctx);

            observer = sTransferUtility.upload(remotepath, file.getName(), file);
            transferObservers.add(observer);

            observer.setTransferListener(new UploadListener(this.progressBar,observer,file.getPath()));

        }

    }
}

【问题讨论】:

    标签: android amazon-web-services amazon-s3 amazon-cognito


    【解决方案1】:
    1. 我能想到两种方法:

      一个。一个简单的尝试/捕捉使用令牌的代码。如果它抛出适当的异常,请获取一个新异常并重试。

      b.使用开发人员身份验证的身份,您可以配置令牌的有效长度。您可以轻松地在应用程序内跟踪它并在它过期时采取适当的行动。这是我推荐的路线。

    2. 我不确定你的意思。 SDK 会在它们被检索后存储它们。可以通过getIdentityId()或者getCachedIdentityId()获取id,为什么需要token?

    3. 理想/推荐的流程是您不必手动对它们执行任何操作。一旦 SDK 拥有它们,您就应该能够使用凭证提供程序来获取您可以访问 S3 的凭证。这意味着保存令牌并重新使用它,但同样,这不应该是您的额外工作。

    编辑:

    您不应该每次都在新线程中重新创建凭据提供程序。它会失去状态,你将不得不不断地联系你的后端。它应该是一个单例,如blog post 和示例(链接在该博客文章中)所示。

    您还应该向提供商提供您在控制台上配置的提供商的密钥,而不是 cognito-identity.amazonaws.com。

    你设置令牌的方式看起来也很奇怪。该示例将登录设置如下:

    CognitoSyncClientManager
                .addLogins(
                        ((DeveloperAuthenticationProvider) CognitoSyncClientManager.provider
                                .getIdentityProvider()).getProviderName(),
                        userName);
    

    我建议再看一下示例,在实现上似乎存在一些差异。

    【讨论】:

    • “这意味着保存令牌并重复使用它,但同样,这不应该是您的额外工作”这是否意味着 API 存储令牌并自动重复使用它?
    • SDK应该,不一定是API。
    • 看起来像。我在我的代码中搞砸了一些东西。我把它贴在这里。请看代码
    • 我是 aws sdk 用法的新手。如果你说我哪里出错了,非常有帮助。应该在哪里添加代码来检索现有的令牌和 IdentityID?这段代码是正确的使用方式吗?
    • 有两件事很突出——你应该使用你在控制台上在 getProviderName() 中配置的提供程序名称,并且(关键的)CognitoCachingCredentialsProvider 绝对应该是一个单例,而不是在每个并行线程中创建时间。这可能是你的关键问题。另外,我想我只是在论坛上回复了你的帖子:p。
    猜你喜欢
    • 2019-03-26
    • 2018-05-22
    • 2021-06-23
    • 2018-12-16
    • 2017-12-30
    • 2019-07-08
    • 2018-08-15
    • 2021-08-28
    • 1970-01-01
    相关资源
    最近更新 更多