aws-amplify / amplify-hosting

AWS Amplify Hosting provides a Git-based workflow for deploying and hosting fullstack serverless web applications.
https://aws.amazon.com/amplify/hosting/
Apache License 2.0
456 stars 115 forks source link

Pass url params in rewrites and redirects #97

Closed patleeman closed 7 months ago

patleeman commented 5 years ago

Please describe which feature you have a question about? Rewrites and redirects

Provide additional details Hello, I'm trying to set up a 301/302 redirect from a path in my amplify application. i.e. /test to another domain i.e. https://example.com/test. The redirect works as expected, but if I try to add some url parameters, /test?utm_test=test the redirect strips the url parameter and redirects to https://example.com/test. With the 200 rewrite, url params don't get stripped.

I want /test?utm_test=test&utm_something=something -302-> https://example.com/test?utm_test=test&utm_something=something

I get /test?utm_test=test&utm_something=something -302-> https://example.com/test

Is there a way to pass along all the url parameters in one shot?

As a side note, I am trying to redirect the path including the trailing slash and excluding the trailing slash. i.e. /test and test/. I know you can use the regex route to do both i.e. </(\/test)(\/)?/> -> https://example.com/test but there doesn't seem to be a way to use path parameters with regex paths?

i.e. </(\/test\/<path_param>)(\/)?/> --> https://example.com/<path_param> or even a way to specify the regex match group? --> https://example.com/<regex[1]> or something like that.

Thanks for the help

hzhenmin commented 5 years ago

1 Currently we do not support redirect with query string, we have added the feature into our backlog 2 <*> can be used to redirect everything after path to another url example: Source: /test/<*> Target: https://example.com/<*> Type: 301/302

patleeman commented 5 years ago

@hzhenmin Thanks for the <> tip. I didn't know you could do that. 👍

We found a workaround for the querystring issue for now. Thank you.

swaminator commented 5 years ago

@patleeman could you share your workaround for other users who end up here?

patleeman commented 5 years ago

@swaminator sure thing.

I ended up doing a 200 rewrite to an endpoint I wrote that returned a 302 redirect to the domain I wanted with the url parameters appended.

Not the best solution but it works for now.

JonVisc commented 4 years ago

@hzhenmin , Re-asking the question that @patleeman asked.

If we use regex to get a capture group, can we reuse that group? </^([^\.]+(?<!\/))$/> will match for: /test

But not match for: /test/ /test.html

So if a user hits https://example.com/test is there anyway to say we want to redirect them to https://example.com/test/ using that capture group?

You mentioned the functionality of a query string in the backlog but I thought more generically it would imply anything in a capture group. Is there an update if that functionality will be out soon/is out but the documentation is lacking so we don't know the syntax?

Adding in my coworker @eisware

berniedurfee commented 4 years ago

This seems to be breaking OIDC callbacks, where the user is redirected from the IdP back to the app route like: https://myapp.com/implicit/callback?code=abcxyz

The user is then immediately redirected by Cloudfront to https://myapp.com/implicit/callback/ without the query parameters, which breaks the OIDC flow.

The only solution was to force a 200 back to index.html using the rewrite rule specified here: https://docs.aws.amazon.com/amplify/latest/userguide/redirects.html#redirects-for-single-page-web-apps-spa

Though, it's not clear how that's working, without seeing the underlying Cloudfront configuration. It simply stops executing the 301, which preserves the query parameters.

@hzhenmin what's the solution proposed to allow redirects while preserving query parameters in Amplify?

poolieweb commented 4 years ago

+1 , We are trying to do RegEx with capture groups. Very difficult to replicate redirects from existing systems.

awilkins commented 4 years ago

Is this feature implemented with a Lambda@Edge? Maybe if we could get access to the source it would become clearer to people?

SudduK commented 4 years ago

This seems to be breaking OIDC callbacks, where the user is redirected from the IdP back to the app route like: https://myapp.com/implicit/callback?code=abcxyz

The user is then immediately redirected by Cloudfront to https://myapp.com/implicit/callback/ without the query parameters, which breaks the OIDC flow.

The only solution was to force a 200 back to index.html using the rewrite rule specified here: https://docs.aws.amazon.com/amplify/latest/userguide/redirects.html#redirects-for-single-page-web-apps-spa

Though, it's not clear how that's working, without seeing the underlying Cloudfront configuration. It simply stops executing the 301, which preserves the query parameters.

@hzhenmin what's the solution proposed to allow redirects while preserving query parameters in Amplify?

Hi berniedurfee,

Did you resolve the issue with OIDC callback url not preserving parameters?

I am trying to implement OKTA authentication (OIDC) for a React based SPA and trying to host the application into AWS Amplify (I tried initially to host SPA in S3 as static website along with Cloudfront and had PKCE errors not supporting http protocol with S3 website endpoint and eventually ended trying to use AWS Amplify)

When deployed to AWS Amplify, application tries to authenticate initially, but redirecting back to callback url (https://domainname.com/implicit/callback) seems to be not routing to the react callback component. I tried using a hack to rewrite the callback url, https://domainname.com/implicit/callback to https://domainname.com/#!implicit/callback in order to route to the Logincallback component, but missing code and state parameters which are required to complete authentication.

Secondly, I was not able to use the regular expression (</^[^.]+$|.(?!(css|gif|ico|jpg|js|png|txt|svg|woff|ttf|map|json)$)([^.]+$)/>) redirect for SPA successfully as given in AWS amplify documentation. This redirect rule is working only until redirecting the callback url to index.html and does nothing after that.

Any thoughts on how to approach this issue? Thank you!

Regards, Sudharshan.

bighoot commented 4 years ago

This seems to be breaking OIDC callbacks, where the user is redirected from the IdP back to the app route like: https://myapp.com/implicit/callback?code=abcxyz

The user is then immediately redirected by Cloudfront to https://myapp.com/implicit/callback/ without the query parameters, which breaks the OIDC flow.

The only solution was to force a 200 back to index.html using the rewrite rule specified here: https://docs.aws.amazon.com/amplify/latest/userguide/redirects.html#redirects-for-single-page-web-apps-spa

Though, it's not clear how that's working, without seeing the underlying Cloudfront configuration. It simply stops executing the 301, which preserves the query parameters.

@hzhenmin what's the solution proposed to allow redirects while preserving query parameters in Amplify?

Were you ever able to resolve this or build a workaround that allowed for query parameters?

FelixRe0 commented 4 years ago

+1 Same question here. Using </index.html/> => /404.html [404 Rewrite] #823

cmaycumber commented 4 years ago

I'm running into the exact same issue using the same setup as @FelixRe0 for a Gatsby site.

bighoot commented 4 years ago

I guess I can say it feels better to not be the only one struggling with this.

bighoot commented 4 years ago

Others at my company have recommended trying to build some sort of component that would be able to redirect to where the traffic needs to go (in my case its the callback after logging in to Okta) and somehow preserve the query parameters. But, unless I misunderstand something, there's literally no way to access those parameters in the app, or any app running in Amplify, because as soon as the call hits that boundary, the query parameters are lost. Is that everyone else's understanding as well? Or am I oversimplifying this?

cmaycumber commented 4 years ago

@bighoot We ended up reaching out to AWS technical support so hopefully they can help; I think that passing query params is a pretty vital task.

That's how it should work. The redirects are handled on the CloudFront edge server rather than the client.

cmaycumber commented 4 years ago

We reached out to AWS support and they said that this is currently not supported; referencing this issue.

@bighoot @FelixRe0 One way that we are currently getting around it is passing the UTM's with the trailing slash on the end of the URL with UTMS like https://www.example.com/products/kit/?example=true. AWS console doesn't remove the query params when the trailing slash is included. Not sure if this supports your use case but it seems like it's working for us for the time being.

bighoot commented 4 years ago

I added the trailing / to the end of the redirect URL and to the callback route in the angular app and, like magic, the redirect that took away the params vanished. Thanks! This seems like a complete hack and I have no idea why it works, but it does. Thank you again.

jlcampos-iies commented 4 years ago

Same problem here... stopping an ec2 and starting amplify... everything ok except some issues... one of them refer to authentication from usr/pwd provider during user registration with specific token and tokenId sent by email to the user.... then the user confirm from email through url similar to https://example.com/confirmRegistry?token=value1&tokenId=value2

Adding trailing slash seems not to solve it.

Any new idea???

Thanks in advance

gwryssekk commented 4 years ago

Hi @jlcampos-iies -- Can you give more detail on your use case? What is the expected result when the user tries to confirm via https://example.com/confirmRegistry?token=value1&tokenId=value2 and what is the actual result?

jlcampos-iies commented 4 years ago

Hi @gwryssekk , parameters are used into component to run the provider function that confirms the registry...

params = new URLSearchParams(window.location.search); token = this.params.get('token'); tokenId = this.params.get('tokenId');

ngOnInit(){ confirmUser(this.token, this.tokenId) .then( () => { ... }) .catch( err => console.log(err)); }

The confirmUser function its an http POST request and params are always null because of Amplify redirects to https://example.com/confirmRegistry removing them. So user never can be confirmed.

Regards, Jose Luis Campos

FelixRe0 commented 4 years ago

Hi @jlcampos-iies -- Can you give more detail on your use case? What is the expected result when the user tries to confirm via https://example.com/confirmRegistry?token=value1&tokenId=value2 and what is the actual result?

Use https://example.com/confirmRegistry/?token=value1&tokenId=value2 and it will work. Notice the / before the query parameters. Still, the amplify team should make any url work...

jlcampos-iies commented 4 years ago

Hi everyone!

Adding from backend / before the query parameters had desired effect.

Thanks again!

Regards, Jose Luis Campos

grahamd711 commented 4 years ago

@hzhenmin has there been any progress in adding support for this feature? This is a critical need for simply redirecting from a naked domain https://example.com to the WWW version --> https://www.example.com

We are not able to preserve any UTM parameters that are crucial to our Jekyll site. Please let me know if there is any type of transparency into the backlog.

Thank you!

carlcassar commented 4 years ago

Can we please have an update on this issue?

I can confirm that @cmaycumber's solution works, but query parameters are an essential feature of web apps. We often don't have control over the code that is calling the uri and can't enforce the addition of a trailing slash.

In my case, I am unable to use Utterances until this issue is resolved since the token is appended to a callback uri that does not add a '/'.

KLaci commented 3 years ago

Any progress with this? It's not okay that I have to update all my links to the ridiculously looking /page/?param=value structure due to the breaking change in Amplify's redirect behavior. I seriously consider migrating to Netlify because of this issue.

Lasim commented 3 years ago

Hi, can someone please provide an update for this issue? I'm using VueJS with nasty workaround for URL parameter.

santinogue commented 3 years ago

Any updates? It is a very necessary feature.

jimmyn commented 3 years ago

I'm also struggling with this. We have moved our website to a new domain and we need to redirect all requests including query params. This is a critical issue for us. Is there any workaround right now?

Calandri commented 3 years ago

Any update?!?!

Calandri commented 3 years ago

Hello, WE NEED THIS feature? Look like AWS is not interest in keepe paying costumer. And AWS it's not cheap. Please. FIX this BUG

iceye commented 3 years ago

+1, same issue, after hours of tests it's impossible to migrate existing routes to amplify. This missing feature it's blocking for me and for a million people like me

Coelmount commented 3 years ago

same issue here

I confirm however that https://myapp.amplifyapp.com/sso/?param1=value1&param2=value2&.... has the desired effect however, this additional / before the ? is not viable.

Can this be fixed please?

caycecollins commented 3 years ago

same issue here

I confirm however that https://myapp.amplifyapp.com/sso/?param1=value1&param2=value2&.... has the desired effect however, this additional / before the ? is not viable.

Can this be fixed please?

I agree. if we construct the links ourselves and send it to somebody, then manually adding the slash would be a fine solution.

However, if a user is at /shop?brand=SomeBrand and wants to bookmark the page, they will get sent back to /shop/ when using the bookmark later.

dparrelli commented 3 years ago

For those who are using the trailing slash hack to resolve this issue, how are you preventing the trailing slash from being automatically removed when the URL loads?

eg. When I refresh a page with a URL that has a query string, this is what happens to the URL: https://myapp.com/section/?id=1 --> https://myapp.com/section?id=1 --> https://myapp.com/section

leofrozenyogurt commented 3 years ago

For those who are using the trailing slash hack to resolve this issue, how are you preventing the trailing slash from being automatically removed when the URL loads?

eg. When I refresh a page with a URL that has a query string, this is what happens to the URL: https://myapp.com/section/?id=1 --> https://myapp.com/section?id=1 --> https://myapp.com/section

this is still an ongoing issue; so the workaround hack isnt great for now

pankajsoni19 commented 3 years ago

Is there any ETA on resolving this? Most of our sites are on Amplify. For this particular issue we would have to migrate couple of our sites to firebase hosting.

Calandri commented 3 years ago

We are going to migrate 4 sites next week for this issue, it's 10 months that we are asking to solve this issue

Il giorno ven 20 ago 2021 alle ore 07:13 Pankaj Soni < @.***> ha scritto:

Is there any ETA on resolving this? Most of our sites are on Amplify. For this particular issue we would have to migrate couple of our sites to firebase hosting.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/aws-amplify/amplify-console/issues/97#issuecomment-902436680, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKPNYQMCMU5EBGANH6HP5YDT5XQBLANCNFSM4ITKFR6Q . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email .

Lasim commented 3 years ago

Any updates?

borisilic commented 3 years ago

Anyone have a good resource for removing Amplify hosting but keeping the rest of the infrastructure? The workaround doesn't work amazingly well with Angular.

pankajsoni19 commented 3 years ago

I confirm things work well with firebase hosting. The deployment/migration is a breeze too, with no downtime.

Calandri commented 3 years ago

Great I will do that soon

Il Sab 21 Ago 2021, 08:09 Pankaj Soni @.***> ha scritto:

I confirm things work well with firebase hosting. The deployment/migration is a breeze too, without much downtime.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/aws-amplify/amplify-console/issues/97#issuecomment-903066498, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKPNYQNUJS2TX4BNM25CDT3T547JLANCNFSM4ITKFR6Q . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email .

watilde commented 3 years ago

For my SPA with a specific query string, I implemented the below routing rule and could make a redirect from /<*>/<*>?id=123 to /index.html?id=123.

[
    {
        "source": "/index.html",
        "target": "/index.html",
        "status": "200",
        "condition": null
    },
    {
        "source": "/<*>?id=<id>",
        "target": "/index.html?id=<id>",
        "status": "301",
        "condition": null
    },
    {
        "source": "/<*>?id=<id>",
        "target": "/index.html",
        "status": "404",
        "condition": null
    },
    {
        "source": "</^[^.]+$|\\.(?!(css|gif|ico|jpg|js|png|txt|svg|woff|woff2|ttf|map|json)$)([^.]+$)/>",
        "target": "/index.html",
        "status": "200",
        "condition": null
    }
]

To make this solution more generic, we might want <QUERY_STRING> variable so that any of query string could be kept.

Example routing ```json [ { "source": "/index.html", "target": "/index.html", "status": "200", "condition": null }, { "source": "/<*>?", "target": "/index.html?", "status": "301", "condition": null }, { "source": "/<*>?", "target": "/index.html", "status": "404", "condition": null }, { "source": "", "target": "/index.html", "status": "200", "condition": null } ] ```

cc @nimacks

doc-l commented 3 years ago

The issue has several components:

I fixed this by doing the following things:

For Gatsby Install gatsby plugin to force trailing slashes (https://www.gatsbyjs.com/plugins/gatsby-plugin-force-trailing-slashes/) -- this is only specific to gatsby

To fix the S3 redirect You can only fix this by routing to a trailing slash before going to S3, so this has to be done in cloudfront with a lambda@edge function, like this one: https://github.com/riboseinc/terraform-aws-s3-cloudfront-website/issues/1

However, you can't change the cloudfront settings of an amplify deploy, so I added this in the test phase of the amplify.yml deploy script:

test:
  phases:
    test:
      commands:
        # Do test things

        # This would be better in postTest, but that runs even when test fails
        - echo "Deploying site to S3"
        # You could here add a thing to exit when not main branch for example
        - aws s3 sync public s3://CUSTOM_S3_BUCKET
        - aws cloudfront create-invalidation --distribution-id YOUR_ID --paths '/*'
        - rm -rf public/*
        - touch public/hoi # necessary for successful pipeline

This deploys your public folder (or change into dist) into your own bucket that you can configure using cloudfront to use the lambda@edge. It then removes the public folder and deploys nothing in the amplify bucket. So you basically use everything from amplify, but circumvent the actual deploy.

I can confirm this 100% works for /x?a=b and /x/?a=b and the querystring also stays when redirecting etc :)

however, it still is quite annoying we need this quite elaborate workaround to get something simple as querystrings working, but I do understand why this is such a long standing issue for the Amplify team: it's actually a limitation of S3.

However, a possible permanent fix would be to allow origin requests in the amplify cloudfront distributions from the amplify settings page.

jonathanbravecredit commented 2 years ago

@watilde your solution worked perfectly. I had to re-order my rules slightly in a different order of preference but after that, it worked perfectly.

tmosmant commented 2 years ago

Hello, this is still needed and unfortunately the workarounds are still workarounds...

Calandri commented 2 years ago

AGree! FIXXXXXXX

Calandri commented 2 years ago

AGREE

Il giorno dom 27 feb 2022 alle ore 17:14 Thomas Mosmant < @.***> ha scritto:

Hello, this is still needed and unfortunately the workarounds are still workarounds...

— Reply to this email directly, view it on GitHub https://github.com/aws-amplify/amplify-console/issues/97#issuecomment-1053603421, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKPNYQM67KORPY53KR5JXO3U5JEXZANCNFSM4ITKFR6Q . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you commented.Message ID: @.***>

parikls commented 2 years ago

Any updates regarding this? It should not work like this

doc-l commented 2 years ago

No it still works like that afaik, we're currently moving away from amplify ci/cd completely to github actions so we have more control. The "solution" I posted earlier is still how we handle things which is running stable for months now, but it's kind of a non-solution.

swaminator commented 2 years ago

@parikls @l-hendriks we just launched support for this: https://docs.aws.amazon.com/amplify/latest/userguide/redirects.html#query-strings-and-path-parameters. Let us know if this works for you.