Angular 2和Symfony 3(OAuth和API调用)

时间:2017-03-22 10:55:48

标签: api symfony angular authentication oauth

我在Angular 2.4.0中有一个项目,我想从Symfony 3 REST API调用端点。这两个项目都在当地推出。为了消除Angular中Http调用中的CORS错误,我设置了一些代理规则如下:

{
  "/api/*": {
    "target": "http://myapi.dev:8000",
    "secure": false,
    "changeOrigin": true,
    "pathRewrite": {"^/api" : ""},
    "logLevel": "debug"
  }
}

第一步是使用Google OAuth进行身份验证,因此我打开一个新的弹出窗口(在我的Angular项目中):

window.open('api/connect/google', '_blank', 'location=yes,height=570,width=520,scrollbars=yes,status=yes');

然后我选择了一个Google帐户进行身份验证,然后API会在成功通过身份验证后自动关闭弹出窗口。

然后我再次调用API以获取当前登录用户:

get(): Observable<User> {
    return this.http.get('api/user')
      .map((response: Response) => response.json())
      .catch((error: any) => Observable.throw(error));
  }

问题是API会抛出以下内容:

Request URL:http://localhost:2222/api/user
Request Method:GET
Status Code:302 Found
Remote Address:127.0.0.1:2222

Access-Control-Allow-Origin:*
cache-control:no-cache, private
connection:close
content-type:json
date:Wed, 22 Mar 2017 10:20:32 GMT
location:http://myapi.dev:8000/login
server:nginx/1.11.10
transfer-encoding:chunked
x-debug-token:128b90
x-debug-token-link:http://myapi.dev:8000/_profiler/128b90
x-powered-by:PHP/7.1.3

Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:no-cache
Connection:keep-alive
Cookie:PHPSESSID=18c73caec383e91904dfd239d1a95faa
Host:localhost:2222
Pragma:no-cache
Referer:http://localhost:2222/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36

似乎API 不知道我已经过身份验证并尝试将我重定向到每个其他<{1}}路由Http我想做的电话。

API的工作原理如下:

  1. / login 是一个小页面,其中包含指向/ connect / google(Google OAuth)的链接
  2. / connect / google 允许您选择一个Google帐户进行身份验证
  3. 如果您在未经过身份验证的情况下调用任何API端点,则会将您重定向到 / login
  4. 如果您经过身份验证,则可以调用每个API端点
  5. 如果我将所有上述Angular Http调用直接调用到浏览器中(例如:http://myapi.dev:8000/connect/googlehttp://myapi.dev:8000/user),一切正常。

    我真的不知道这个问题来自哪里。

1 个答案:

答案 0 :(得分:0)

正如您在评论中所说,Angular应用程序托管在http://localhost:2222/上,但api托管在http://myapi.dev:8000上。这两个起源完全不同。这意味着当myapi.dev开始会话时,设置Cookie,它将在localhost上不可用。浏览器不允许发送来自不同来源的cookie(由于CORS)。这就是为什么api看不到你的会话ID密钥。

克服问题的可能方法:

  1. 将两个应用程序(angular和api)存储在同一个源(它意味着相同的域,相同的协议和相同的端口) - 这是最简单的方法。
  2. 捕获会话ID cookie值(就在设置之后)并将其存储在sessionStorage中。接下来,创建Angular的请求拦截器,它将把SESSION cookie添加到所有要进入myapi.dev的请求