最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angular 4 not send cookie to server - Stack Overflow

programmeradmin2浏览0评论

When I use withCredentials I can see that cookies are sent to the server, but are send anything to the server. I use laravel as backend and angular 4 as frontend. Also, the cookie not shown on chrome developer tools and I can't access them using.

Also, I used Cors middleware in laravel like:

<?php

namespace App\Http\Middleware;

use Closure;

class Cors
{
    /**
     * Handle an ining request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
      $response = $next($request);
      $response->headers->set('Access-Control-Allow-Origin', 'http://localhost:4200');
      $response->headers->set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
      $response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Request-With');
      $response->headers->set('Access-Control-Expose-Headers', 'Content-Disposition, x-total-count, x-filename');
      $response->headers->set('Access-Control-Allow-Credentials', 'true');

      return $response;

    }
}

and when I request first time to the server for set cookie, these below response show:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Content-Type, Accept, Authorization, X-Request-With
Access-Control-Allow-Methods:GET, POST, OPTIONS, PUT, PATCH, DELETE
Access-Control-Allow-Origin:http://localhost:4200
Access-Control-Expose-Headers:Content-Disposition, x-total-count, x-filename
Cache-Control:no-cache, private
Connection:keep-alive
Content-Type:application/json
Date:Tue, 02 Jan 2018 09:04:32 GMT
Server:nginx/1.11.9
Set-Cookie:refreshToken=def502005a2ccf60eafdee2137df25a628d49f70c4571bedde628d50e45c0fe4b73f84f86bb469f0f77247dc2abc13c0c5c938027beb13fe534eb7bb41f4aed99faf49ebf2a238a007ce9514108951366db45a311d70d17d65dd48f5df6aa50f257c828cce16e589983c1e06c9e8d7d52806a1a9401569f87b3a394469e938c4ddbfcc7985e257d8f0d0df416e7b8a5bbd19e86050db3be5b90953c515934f529489f4e0ba62fb66ab883d1689349bbfb962332bceb322d978b7d20fa7e32bb94eb0050d8f94bfd3a780c4edfeea8eaa6954222b57c30229c2494fec38ee5292396400b25fadee04cad1729f9e9b9ccf12d21a6ed3f9663d41c5423536e64f83542df19fcede28247bfc12accf354e035182c3e019e4a2b55c807924cc50a12fa187b2f655fb19c1b42a1ae526763dd08dbd0d288b3a9c649216ab1abc60cd51bb97dfb0cb7b7b020ff270cf5c81bc94f2acd40f92edeefaf585d46d0750bf; expires=Sun, 25-Aug-2019 09:04:32 GMT; Max-Age=51840000; path=/; HttpOnly
Transfer-Encoding:chunked
X-RateLimit-Limit:60
X-RateLimit-Remaining:58

and when I request from frontend:

refreshToken(){

const headers = new Headers({ 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + this.getToken()})
let options = new RequestOptions({ headers: headers, withCredentials: true });
return this.http.post(API_DOMAIN + 'refresh', JSON.stringify({}), options)
  .map(
    (response) => {
      console.log(response);
      return response.json()
    },
  )
  .do(
    tokenData =>{
      localStorage.setItem('token', tokenData.access_token)
      localStorage.setItem('expires_in', tokenData.expires_in)
    }
  )
}

Chrome developer:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Content-Type, Accept, Authorization, X-Request-With
Access-Control-Allow-Methods:GET, POST, OPTIONS, PUT, PATCH, DELETE
Access-Control-Allow-Origin:http://localhost:4200
Access-Control-Expose-Headers:Content-Disposition, x-total-count, x-filename
Cache-Control:no-cache, private
Connection:keep-alive
Content-Type:application/json
Date:Tue, 02 Jan 2018 08:57:28 GMT
Server:nginx/1.11.9
Transfer-Encoding:chunked
X-RateLimit-Limit:60
X-RateLimit-Remaining:59

Front and back servers use different ports.

When I use withCredentials I can see that cookies are sent to the server, but are send anything to the server. I use laravel as backend and angular 4 as frontend. Also, the cookie not shown on chrome developer tools and I can't access them using.

Also, I used Cors middleware in laravel like:

<?php

namespace App\Http\Middleware;

use Closure;

class Cors
{
    /**
     * Handle an ining request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
      $response = $next($request);
      $response->headers->set('Access-Control-Allow-Origin', 'http://localhost:4200');
      $response->headers->set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
      $response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Request-With');
      $response->headers->set('Access-Control-Expose-Headers', 'Content-Disposition, x-total-count, x-filename');
      $response->headers->set('Access-Control-Allow-Credentials', 'true');

      return $response;

    }
}

and when I request first time to the server for set cookie, these below response show:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Content-Type, Accept, Authorization, X-Request-With
Access-Control-Allow-Methods:GET, POST, OPTIONS, PUT, PATCH, DELETE
Access-Control-Allow-Origin:http://localhost:4200
Access-Control-Expose-Headers:Content-Disposition, x-total-count, x-filename
Cache-Control:no-cache, private
Connection:keep-alive
Content-Type:application/json
Date:Tue, 02 Jan 2018 09:04:32 GMT
Server:nginx/1.11.9
Set-Cookie:refreshToken=def502005a2ccf60eafdee2137df25a628d49f70c4571bedde628d50e45c0fe4b73f84f86bb469f0f77247dc2abc13c0c5c938027beb13fe534eb7bb41f4aed99faf49ebf2a238a007ce9514108951366db45a311d70d17d65dd48f5df6aa50f257c828cce16e589983c1e06c9e8d7d52806a1a9401569f87b3a394469e938c4ddbfcc7985e257d8f0d0df416e7b8a5bbd19e86050db3be5b90953c515934f529489f4e0ba62fb66ab883d1689349bbfb962332bceb322d978b7d20fa7e32bb94eb0050d8f94bfd3a780c4edfeea8eaa6954222b57c30229c2494fec38ee5292396400b25fadee04cad1729f9e9b9ccf12d21a6ed3f9663d41c5423536e64f83542df19fcede28247bfc12accf354e035182c3e019e4a2b55c807924cc50a12fa187b2f655fb19c1b42a1ae526763dd08dbd0d288b3a9c649216ab1abc60cd51bb97dfb0cb7b7b020ff270cf5c81bc94f2acd40f92edeefaf585d46d0750bf; expires=Sun, 25-Aug-2019 09:04:32 GMT; Max-Age=51840000; path=/; HttpOnly
Transfer-Encoding:chunked
X-RateLimit-Limit:60
X-RateLimit-Remaining:58

and when I request from frontend:

refreshToken(){

const headers = new Headers({ 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + this.getToken()})
let options = new RequestOptions({ headers: headers, withCredentials: true });
return this.http.post(API_DOMAIN + 'refresh', JSON.stringify({}), options)
  .map(
    (response) => {
      console.log(response);
      return response.json()
    },
  )
  .do(
    tokenData =>{
      localStorage.setItem('token', tokenData.access_token)
      localStorage.setItem('expires_in', tokenData.expires_in)
    }
  )
}

Chrome developer:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Content-Type, Accept, Authorization, X-Request-With
Access-Control-Allow-Methods:GET, POST, OPTIONS, PUT, PATCH, DELETE
Access-Control-Allow-Origin:http://localhost:4200
Access-Control-Expose-Headers:Content-Disposition, x-total-count, x-filename
Cache-Control:no-cache, private
Connection:keep-alive
Content-Type:application/json
Date:Tue, 02 Jan 2018 08:57:28 GMT
Server:nginx/1.11.9
Transfer-Encoding:chunked
X-RateLimit-Limit:60
X-RateLimit-Remaining:59

Front and back servers use different ports.

Share Improve this question edited Apr 1, 2024 at 14:28 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Jan 2, 2018 at 9:07 MilanoMilano 1763 silver badges17 bronze badges 7
  • 1 Does your Laravel server run of localhost too? Why do you need CORS? – Dmitry Commented Jan 2, 2018 at 11:52
  • @Dmitry no. my laravel server run on homestead and domian like: mydomian.test – Milano Commented Jan 2, 2018 at 12:32
  • You can't send/receive cookies to/from another domain. You need to either proxy to your Laravel server (can be configured in angular) or use another authentication method like JWT or other token based authentication. – Dmitry Commented Jan 2, 2018 at 12:38
  • @Dmitry I used laravel passport for authentication and write middleware in laravel server! – Milano Commented Jan 2, 2018 at 12:43
  • Ah, so they are not authentication cookies. But you can't send any cookies to another domain anyway. You can use proxy and then you can disable CORS since it will work on the same domain. You only need proxy for development since when you publish your entire app will be in Laravel's public directory. Do you want me to post how to configure the proxy? – Dmitry Commented Jan 2, 2018 at 12:51
 |  Show 2 more ments

1 Answer 1

Reset to default 5

You can't save cookies because your development node.js server and your Laravel Vagrant box are on different domains. What you can do is to proxy calls from node.js to the the Laravel server.

Create proxy.conf.json in the root of Angular app. Put an object with routes inside:

{
  "/api": {
    "target": "http://mydomian.test/",
    "secure": false
  }
}

I just have /api defined here because all my backend URIs are inside api.php. All calls that look like http://localhost:4200/api/someitems/1 will be proxied to http://mydomian.test/api/someitems/1.
Then edit package.json and change the value of start inside scripts to ng serve --proxy-config proxy.conf.json. Now npm run start will start with proxy. The problem I had with this proxy is that it resolves your URL (http://mydomian.test/) to an IP. When it calls Laravel with just an IP the nginx server does not know what to do because it must receive a domain name. nginx allows multiple website on the same IP so it must receive a domain name or to have a default website to which it redirects all calls those have no domain name. In case this is still not fixed in Angular's proxy go to /etc/nginx/sites-available on the Laravel machine, you'll have a mydomian.test config file there. It has listen 80; line there, change it to listen 80 default;.

Now you can change the API_DOMAIN variable to http://localhost:4200 (or remove it all together) and disable the CORS.

发布评论

评论列表(0)

  1. 暂无评论