代码之家  ›  专栏  ›  技术社区  ›  Shrouk Khan

React native/AWS API网关android问题

  •  4
  • Shrouk Khan  · 技术社区  · 8 年前

    var signedRequest={
      "headers": {
        "Content-Type": "application/json",
        "Accept": "application/json",
        "x-amz-date": "20170918T134411Z",
        "Authorization": "AWS4-HMAC-SHA256 Credential=ASIAIBC7RQ7MFUIRO7QQ/20170918/ap-northeast-1/execute-api/aws4_request, SignedHeaders=accept;content-type;host;x-amz-date, Signature=9fb6d4d4820024097f25aaa70648fxxx7a54a2db1a67d173189693dc073d0a0bac8",
        "x-amz-security-token": "AgoGb3JpZ2luEKn////////xxxG1iKJBHjjvZH0DxcSqE889Wb3Mv+8PwMqrRe/O5dFFmP+9bQj+fSwVIUvmBplKkQB62x/xTelGHoCEOPXpBWLjT2OAUaBXOti7UZyfyMNgg56/Z58yxk4o2/37xPLbhXfODaL8kydFV8IaPJjdbJIX+a0kXycPLBnVIBdukUp9cMVD27mWN41u3w0VP5J8YiMPzrDnwKtb0U37naoIaknMBqNBDkMGQyHal/TBJ3wjJvJWVntrJvex0QKD8rDLHjaoiIYjBd+a04m2pKsBQJ9WQl02TTCPgRp0bb1oARF2hz0Xpi45Ba6a6E9SAL07UcRShTwX6rmxi0dZ38mkSbBMjI45Xg8r/VaRZx6/OyCq3u+nq4bgLCOMKqb/80F"
      },
      "data": "{\"data\":{\"func\":\"checkIfFacebookSignupComplete\",\"data\":{}}}",
      "method": "POST",
      "url": "https://xxx.execute-api.ap-northeast-1.amazonaws.com/dev/user/user"
    }
    
    var apiResponse=await fetch(signedRequest.url, {
    
      method: signedRequest.method,
      body: signedRequest.data,
      headers: signedRequest.headers,
    
    })
    console.log("Got api response : ", apiResponse)
    

    在iOS上,它接收http响应200。然而,在android上,它失败了:

    The Canonical String for this request should have been
    'POST
    /dev/user/user
    
    accept:application/json
    content-type:application/json; charset=utf-8
    host:uihw7hnkn7.execute-api.ap-northeast-1.amazonaws.com
    x-amz-date:20170918T134411Z
    
    accept;content-type;host;x-amz-date
    6b83b80f2875c2425c28b258886ad98603fd802095e35303a3c2a72528374fb5'
    
    The String-to-Sign should have been
    'AWS4-HMAC-SHA256
    20170918T134411Z
    20170918/ap-northeast-1/execute-api/aws4_request
    008853cdfba53255257d9169e1a9c05500d01299da9efd4695ac8c66cb31e5e7'
    "
    

    我也试过axios。同样的结果。(ios运行良好,android失败)我使用的是react native 0.42.3。

    有人知道可能是什么问题吗?

    3 回复  |  直到 8 年前
        1
  •  3
  •   Shrouk Khan    8 年前

    经过大量挖掘,问题似乎与以下所述有关: https://github.com/facebook/react-native/issues/14445 . android okHttp库(react native内部使用)向请求中添加了字符集=utf=8。因此,解决方案是使用如下标题计算sig4值:

      var signedRequest={
      "headers": {
        "Content-Type": "pplication/json; charset=utf-8",
        "Accept": "application/json",
        "x-amz-date": "20170918T134411Z",
        "Authorization": "Calculated sig4 auth",
        "x-amz-security-token": "AgoGb3JpZ2luEKn////////xxxG1iKJBHjjvZH0DxcSqE889Wb3Mv+8PwMqrRe/O5dFFmP+9bQj+fSwVIUvmBplKkQB62x/xTelGHoCEOPXpBWLjT2OAUaBXOti7UZyfyMNgg56/Z58yxk4o2/37xPLbhXfODaL8kydFV8IaPJjdbJIX+a0kXycPLBnVIBdukUp9cMVD27mWN41u3w0VP5J8YiMPzrDnwKtb0U37naoIaknMBqNBDkMGQyHal/TBJ3wjJvJWVntrJvex0QKD8rDLHjaoiIYjBd+a04m2pKsBQJ9WQl02TTCPgRp0bb1oARF2hz0Xpi45Ba6a6E9SAL07UcRShTwX6rmxi0dZ38mkSbBMjI45Xg8r/VaRZx6/OyCq3u+nq4bgLCOMKqb/80F"
      },
      "data": "{\"data\":{\"func\":\"checkIfFacebookSignupComplete\",\"data\":{}}}",
      "method": "POST",
      "url": "https://xxx.execute-api.ap-northeast-1.amazonaws.com/dev/user/user"
    }
    
        2
  •  1
  •   Richard    8 年前

    新的AWS放大库( https://github.com/aws/aws-amplify )在官方AWS上,repo支持自动签名到API网关。这是API模块的一部分: https://github.com/aws/aws-amplify/blob/master/media/api_guide.md

    npm install aws-amplify-react-native
    

    https://github.com/aws/aws-amplify/blob/master/media/quick_start.md#react-native-development

    import Amplify, { API } from 'aws-amplify';
    Amplify.configure(
        Auth: {
            identityPoolId: 'XX-XXXX-X:XXXXXXXX-XXXX-1234-abcd-1234567890ab',     //REQUIRED - Amazon Cognito Identity Pool ID
            region: 'XX-XXXX-X', // REQUIRED - Amazon Cognito Region
            userPoolId: 'XX-XXXX-X_abcd1234', //OPTIONAL - Amazon Cognito User Pool ID
            userPoolWebClientId: 'XX-XXXX-X_abcd1234', //OPTIONAL - Amazon Cognito Web Client ID
        },
        API: {
            endpoints: [
                {
                    name: "ApiName1",
                    endpoint: "https://1234567890-abcdefgh.amazonaws.com"
                },
                {
                    name: "ApiName2",
                    endpoint: "https://1234567890-abcdefghijkl.amazonaws.com"
                }
            ]
        }
    });
    

    然后,使用用户的凭据对API网关请求进行签名:

    let apiName = 'MyApiName';
    let path = '/path'; 
    let myInit = { // OPTIONAL
        headers: {} // OPTIONAL
    }
    API.get(apiName, path, myInit).then(response => {
        // Add your code here
    });
    
        3
  •  1
  •   tomatentobi    8 年前

    GET 在两个平台上都工作过,但是 POST 仅在iOS上。背景 Content-Type "application/json; charset=utf-8" 在与签署请求之前 sigV4Client

    const path = 'https://your-aws-endpoint.com';
    const method = 'POST';
    const queryParams = {};
    const body = {};
    const headers = {
        'Content-Type' = 'application/json; charset=utf-8';
    };
    
    const client = sigV4Client.newClient({
        accessKey: ACCESS_KEY,
        secretKey: SECRET_ACCESS_KEY,
        sessionToken: SESSION_TOKEN,
        region: REGION,
        endpoint: ENDPOINT,
    });
    
    const signedRequest = client.signRequest({
        method: method,
        path: path,
        headers: headers,
        queryParams: queryParams,
        body: body
    });
    
    fetch(signedRequest.url, {
        method: method,
        headers: signedRequest.headers,
        body: JSON.stringify(body)
    }).then((results) => {
        ...
    });