angular / angular-cli

CLI tool for Angular
https://cli.angular.io
MIT License
26.74k stars 11.98k forks source link

Store session cookies and proxy #4031

Closed matodrobec closed 7 years ago

matodrobec commented 7 years ago

Hi, Session cookie is not set in browser when I am using proxy

ng serve --proxy-config proxy.conf.json

proxy config:

{
  "/api": {
    "target": "https://test.org",
    "secure": false
  }
}

javascript:

const body = new window.URLSearchParams();
body.set('username', credentials.username);
body.set('password', credentials.password);

let loginHeaders = new Headers();
loginHeaders.append('Content-Type', 'application/x-www-form-urlencoded');

this.http
      .post(`http://localhost:4200/api/auth`, body.toString(), {
        headers: loginHeaders,
        withCredentials: true
      })

How can i set up proxy to store the session cookie in browser? What I am doing wrong?

OS?

Windows 10

Versions.

angular-cli: 1.0.0-beta.24 node: 6.9.1 os: win32 x64

mmrath commented 7 years ago

Not 100% sure if this will work, but did you try

"changeOrigin": true

{
  "/api": {
    "target": "https://test.org",
    "secure": false,
    "changeOrigin": true
  }
}

Also if you could provide all the headers received when you call the api, that will help investigate.

hansl commented 7 years ago

@matodrobec Please try mmrath's solution above to see if it works. If not, you can let me know and I'll re-open this issue. Thanks!

matodrobec commented 7 years ago

@mmrath Thx. I am tested your solution but it is still not working. The session cookie is not stored in browser and the server generate always new session cookie for each request.

My hotfix is

document.cookie = `JSESSIONID=${this.env.sessionCookie}; path=/`;

Now I ask provider api and I would like to use this solution https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials but do not forget read note in "Important note" about setting Access-Control-Allow-Origin

But also will be good to know how to set up proxy to store session cookies.

avella-liaison commented 7 years ago

I'm having the same exact problem, cookies set by the service aren't being set in the browser for subsequent calls.

My json looks like the following:

{ "/rest/*": { "target": "http://localhost:8080/", "changeOrigin": true, "secure": true, "logLevel": "debug" } }

I've tried with both secure true and false, neither helps. I've also started Chrome with the --disable-web-security flag

This is using Angular-cli@1.0.0-beta.21

raviganesh12 commented 7 years ago

Any update on this issue? I have the same problem the secure headers which are coming in the response form server are not send back in request after authentication.

bheemanagouda commented 7 years ago

I too have the same problem, JSESSIONID is not set in browser when api requests are proxied. Any help is much appreciated.

atpjd commented 7 years ago

Same problem here. Angular CLI 1.0.0-rc.2

gseabrook commented 7 years ago

@hansl Is it possible to reopen this issue because its still a problem for some of us

mmrath commented 7 years ago

@gseabrook I have not looked deep enough but i think it is probably how webpack dev server proxy works. CLI uses webpack underneath, if you can provide a repo where it works with webpack for a similar setup, I might be able fix in CLI.

tarun-nagpal-github commented 7 years ago

Hi,

I have converted my project to CLI. But i am having this error while running proxy.

[HPM] Proxy created: /api -> https://test.org [HPM] Subscribed to http-proxy events: [ 'error', 'close' ] [HPM] GET /api/generics-management/getCategoryList -> https://test.org [HPM] Error occurred while trying to proxy request /api/generics-management/getCategoryList from localhost:4200 to https://test.org (ECONNREFUSED) (https://nodejs.org/api/erro...

Can you please help?

ksondhi commented 7 years ago

Hi,

We are currently experiencing the same issue. We are using Angular 2 with the the CLI (v2.4.10), with the proxy.conf.json. The session cookie is not being stored in the browser.

We do have the "changeOrigin": true value set, as suggested in this thread above. I see this issue has been closed. Does anyone have a fix?

Thanks!

CC: @hansl

keithwinn commented 7 years ago

Experiencing same problem. (cli v1.0.0). Can issue be re-opened? Any suggestions for a workaround?

zpc888 commented 7 years ago

I bumped into the same issue for our project and spent the whole day to tried different combinations, and finally make it works. Here is the summary to feedback to the community and hope it can save you a few hours.

when deploying AOT angular 4 project into the same tomcat container hosting backend restful API, the JSESSIONID is sent back after logged in. But when using proxy, to forward backend API from developer box webpack dev server to tomcat server, JSESSIONID is lost, tomcat treats every request is a new request. In webpack dev node server, we use http and tomcat server we use https, it looks like JSESSIONID can not carry over across http --> https. By setting breakpoint after login, try to get JSESSIONID cookie manually via browser debug console and it returns null, but in the login restful API, response header shows: Set-Cookie:JSESSIONID=EEE46B0120F10BA6939EAB2F8AD2CA44;path=/;Secure;HttpOnly

My initial tries to change our spring boot configuration: server.session.cookie.secure=false to hope it can force JSESSION not secure to UI, but it seems no effect if SSL is on.

Then tries to add response headers " Access-Control-xxx" at server side, and "withCredentials=true", "X-Forwarded-Proto=https" for angular request headers, and try to configure "cookieDomainRewrite" in proxy.config.json file, but none of them work.

At the end, I created a self signed cert with openssl and enable node dev server to HTTPS, it works perfectly, then I deleted server side response headers and client side request headers, it seems working fine too.

Here are the related factors for working version:

  1. package.json "start": "ng serve --proxy-config proxy.api.json --ssl true --ssl-key ssl/server.key --ssl-cert ssl/server.crt",
    1. proxy.api.json { "/api": { "target": "https://dit.server:8080", "secure": false, "logLevel": "debug", "changeOrigin": true }, "/login": { "target": "https://dit.server:8080", "secure": false, "logLevel": "debug", "changeOrigin": true }, "/logout": { "target": "https://dit.server:8080", "secure": false, "logLevel": "debug", "changeOrigin": true } }
    2. request headers: let headers = new Headers(); headers.append("Content-Type", "application/json"); headers.append("Access-Control-Allow-Credentials", "true"); headers.append("Access-Control-Allow-Origin", "*"); headers.append("Cache-Control", "no-cache"); // due to IE browser caches API get requests
    3. spring boot application.properties related to ssl server.port=8080 server.ssl.key-store=file:///opt/app/dit.jks server.ssl.key-store-password= server.ssl.key-password=
    4. no response headers added in our Http Servlet Filter class
keithwinn commented 7 years ago

zpc888's method worked. The key item was:

At the end, I created a self signed cert with openssl and enable node dev server to HTTPS, it works perfectly, then I deleted server side response headers and client side request headers, it seems working fine too.

SwapnilKate commented 7 years ago

My issue is when my server context is default '/' on spring boot the proxy config works and all request after successful auth call carry the same jsessionid value.

But once say I change my server context to '/abc' then each subsequent request after auth call caries a different jsessionid and hence I get 302 for all request.

I have used 'changeorigin' true also but it did not work. And I am using tomcat on HTTP only.

Any help would be appreciated.

guoguogis commented 7 years ago

perfect

krishnanmk commented 6 years ago

@zpc888 's technique works. Thanks.

Quick note

The serve command ng serve --proxy-config proxy.api.json --ssl true works too, without requiring the SSL certificate or key, of course except that the browser gives you an "unsafe - caution advised" warning, which does not matter in local env. So once you are past that, you are good to go.

Another lesser-advised alternative

When experimenting, I found that, if your server-side API has auto-redirection of http requests to https handled, then the following works too:

{
    "/api": {
        "target": "http://www.external-api.com",
        "changeOrigin": true,
    },
    ....
}

Note that target protocol is set as http. However, this is totally unsecure, hence avoidable even in dev environments.

SamanthaAdrichem commented 6 years ago

I am facing the same issue, trying out the ssl fix. If that works, the reason is (atleast here) simple. The cookies that are set are SSL only cookies. Your request isn't ssl. The browser doesn't send them back.

4kochi commented 6 years ago

I am not sure if it's the same problem, but we also have the issue that the browser does not send the cookies. In our case the app is served by the cli (ng serve --proxy-config config/proxy.conf.json --environment local_dev --port 9000) and runs at localhost:9000. And the backend is our dev system at dev.wayne.com. All api calls go to the dev backend. But since the browser did not send the cookies when calling the backend, we always get a 401.

The solution was to enable the option withCredentials (https://angular.io/api/http/RequestOptionsArgs#withCredentials) in the RequestOptionsArgs (We are using the deprecated @angular/http). Now it works fine.

rafaelestevaofoster commented 6 years ago

HI, i have a problem safari on IOS 10.3.3

i using this.cookieService.set ('Test', 'Test token criado'), but only IOS 10.3.3 does not work.

is there work around?

Project angular.

public login(login: Login) { let headers = new Headers({ 'Content-Type': 'application/json' }); let options = new RequestOptions({ headers: headers }); return this.http.post(${this.config.apiUrl}/account/login, JSON.stringify(login), options) .map((resposta: Response) => { if (resposta.status == 200) { let token = resposta.json() && resposta.json().token if (token) { this.cookieService.set('XSRF-TOKEN', this.retornarAntiForgery, dataExpiracao, "/"); } } return resposta; }); }

tonyoz44 commented 5 years ago

Hi,

I'm using option.cookiePathRewrite for rewriting the path headers . So, i added this option on my config proxy.Now, the cookie is stored and is sent to each request.

jkyoutsey commented 5 years ago
Angular CLI: 6.2.3
Node: 8.11.4
OS: darwin x64
Angular: 6.1.8
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.8.3
@angular-devkit/build-angular     0.8.3
@angular-devkit/build-optimizer   0.8.3
@angular-devkit/build-webpack     0.8.3
@angular-devkit/core              0.8.3
@angular-devkit/schematics        0.8.3
@angular/cli                      6.2.3
@ngtools/webpack                  6.2.3
@schematics/angular               0.8.3
@schematics/update                0.8.3
rxjs                              6.3.2
typescript                        2.9.1
webpack                           4.19.1

I'm proxied to a test server that does not have SSL, so that is not my issue. I see two 307 redirects in Chrome dev tools Network tab. They both contain the cookie. But the final call to the API does not. 401 Unauthorized because the cookie isn't present.

krishnanmk commented 5 years ago

@jkyoutsey I have been noticing something similar in my app as well after the most recent upgrade to Angular 6 (done last week). It definitely must be some configuration issue. In my specific case, it not working even for a production build (ng build --prod - which is then hosted separately/manually in the same web-server my server API resides in, hence no question of domain or SSL setting mismatch). Is your production build working fine?

jkyoutsey commented 5 years ago

@kichnan we refined our CORS configuration a bit to be more in line with the spec on MDN. But the reality was that the API we were calling just wasn't the right endpoint. I'm not sure our issue is resolved. But we've gotten past it. That API just was bad on the server side. All of my other calls are, in fact, passing the cookie just fine.

stephengardner commented 5 years ago

What's the answer Angular?

lanchana commented 5 years ago

+1

fabianedl777 commented 5 years ago

+1

alexandre-h commented 5 years ago

Hello, any update on this issue?

yuremboo commented 5 years ago

+1

krishnanmk commented 5 years ago

Adding some random helper tips to troubleshoot this issue as I can remember them. Hope this helps.

  1. Make sure that the URL you are proxying is accessible.
  2. If you are using ng serve --ssl true, make sure that the proxied server's SSL certificates are valid. For e.g., a self-signed locally generated certificate, though works in a browser, does not work for me in this situation, and especially over a network (LAN or internet).
  3. If you are using --ssl true, ensure that your proxy configurations have them set with "secure": true. Also try setting "changeOrigin": true.
  4. If you are using --ssl true, try keeping the server URL's "target" link as "https://" based even though auto-redirects (from http to https) may have been configured in the server.
christophedemey commented 5 years ago

I also had this problem, my final solution was this :

{
  "/api": {
    "target": "https://eventbroker-development.azurewebsites.net/api",
    "secure": true,
    "pathRewrite": {
      "^/api": ""
    },
    "changeOrigin": true,
    "logLevel": "debug",
    "withCredentials": true,
    "headers": {"Cookie":".AspNetCore.Cookies=CfDSSPKlUbmmqztPtpwdlsJqOPNIa3pjBw8MxFR4cc0z3cRVJgKDcCKxfxR-f8QEsUFzEh8Ch5iUiX0l_8XyleVjQRg2Cs1pq6dwhqBVcyqwsqcUdb8-l_ruFj6MqFEV3aYJqVnBlwTL-E9jRQALK6fRUv4PdWVyCTvDb3YNfSGntPjQx_sgA-5Q6b-L5Cps6TqxneQuE-zfzXocDO6H6496L3Ijyl5e5l6L5d2PgZNqpO5aHOHXvPxt5RkwXhinnk8Z6ynwAQoNc1obdRdfgvu8MwUWRvhkfgyAtiiy_2fwQP4kQ9429l-6f-o_5LV-N4MJUz4_am8Ci34EDOR6T1K0w2xoOeuvAH-eGhv6QoX30V9ZHWshMeYMtfMax7o2u0hI9vNetzSwGWlvhpbh1aS7wOyzaQmfpXwh7CeyEzdxhIbVO1cg1kLe5PTZpYZqBr-DIBcOOROXYJzr8mUKixvBiROnIl1qpKYt8_YP2Ra5kSurBJF9OhYB7qiMpQDe6nMYA7nlIiF_f72eDYfPVh3tnV0MuXUS6rV3raOj2qjd1C0RE69_DP61lMaMFgfbbLie4i7CvcddYEOJAJYnpSgWrA9lKsYilsHr2cDsMrOLfGXibi-9dU1n1oDvyZ3Mo3pAi5aMTiJhzf4CiNk9lOKd4nelAqOJAH3-CBftexi0P8o0PFIjVOhfBhIVqUmYnKsO8L6ffREjpw4VqxxqNbh1IIG8dTrCmtvB8r06ZFotrhX-TPxzZpd18QgH2OvRBZflo1kBrdmAlekS4HFXRTgi26GQBbfi9zeIev0BTGJzXX0Qr7wG8tIL0uWlo1aC-RgP-tlIYPMZJoSP3mcopF9voFxFYRmW1kdJsOENTGt2R1E-lKjVrxJu-E45ZYZtQzKRs9yxIUogDMD484B2qT3OsTe2zZcLNHXkwgtdYIDDcZRCs3AuNx9UhiBSKb3GlVJHlkI4TkDYqTmBu0U8rAGkKrwN1J7Uki29-SqGbLLbrsJiEEgG9tlRJZL65R3GYyfPwRP8mvsM9gaKlV8ENv7qEs7uGdFjGTNwf0MgYqmuxrJE5zKzeK9ZoQDZ8mmnTF4Dk52-TnnSNM1gNWH9EYIQGwq9OluZ3okdlxw1eJY15Zn9w6G7jPvAL9eodB3UzcWI9XiXk53Zo3mua6k2p3OVC1tU0R0XblvjtGv9VyM88mFOcjm5tpa9hpZiFZHjltRgiAzz6BgO7AfYDjiDvgM_OFuBnwoJtuXDOLeMos-zVbiaQVRVujD-5gcGlfQxUJO39ZPVPNEbBo6gbJO1XwiS-WJCSX_qBdksz2y_TUTeCzfmPNkieTsITr-leOUysI5wYFZVvW1FH8yDEPaEDbHs9fqLliDgn1AMzx1ffyv8KJ0bGi9D8oxgYVRU8XTtYbWl7-eA9sIBeOtGcbkY9Ure-ELwgP0PgCpHBTbYKSUFZ1hhDrcP4Fr66rMMDv61gYnffAXpyKQuLb6Wz-cJc2ljFiGQGLoMNdFHPHw3D6dYrzSndPm6G-2o95LI-MPaGbLUSkMNVJvgbz0i3lo7-ungmD8NeqE-0LXAu95DePp3-OmZPGGpFKylZD3w93riBFYAbxIa4ALP9mF1CFDeoSI-DosVZZWg-W-zNfwK5X6iACQH7XvbE4iOInIU19MjVd-f1l4kOj1EFVb7s5gjHE2RuHnPTOfWrOS17iGhElVbalSSI4yAhfEEWln4S0SZSf2Ml9Rb_XfEjrmR5DnhEw0bby6ubbSrYxGNG6bqfLh93WOgReGLER2Z_OufPCxHTMtOa48pYRBpMtOlnX1z_Kj1v2bcfqAFeIZGvNFl-wgzGK3r29KmLCWnd32nvWQItRyzjSWrenLM9vLRoL49dKJL2U2bqmr7haGQKh9Jup-PofQoVsQdGPypBWEoyTGVW-tp0OmLvwGnshjx4Dwcu9MDrHghzIuC2-oE281Gnk8qeSeyEzg_rA0-1-xdWG_WI05e0i6xLMOQUFKlDoanvYi6oiSsO0JELfppK7s2N7BwcW-6yta5jfx9Zhc0y62m5RHi6c0I2PJubdBVYN0s1LXT27dMd55TuPMw57o_Rwb1D4i27lX8pk4EpE78MGa1ueXGL0VYeu-xoei3xOzoS4FuXEvp17oOncgDnXZMPdeecKOBoCIbDF1oLnwT6OGztMxfLIjlQMqEM84F85JZ6gGmDRWOxRdovwxa0aEqT7pNP_GSV0ycQzicZg8ZeO5a8-iplx4Rpna0AGiAa2aAygiV89OWYlPs9ijmWSpIO0BF3tDZmB78-EuHrF96cYg_hKCsZOVsq_aTIFUUsPLjcAVvfjJ0DKzdCCUCmKTCeQJdjR2Q-WH8AkAvV3NpdHhZ-yqVJf6dR1dfUBmVt9W5LAXrgAB"}
  }
}
angular-automatic-lock-bot[bot] commented 5 years ago

This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.