Angular 2未使用JWT身份验证发送授权标头

Angular 2未使用JWT身份验证发送授权标头,angular,cakephp,get,header,authorization,Angular,Cakephp,Get,Header,Authorization,我试图创建一个应用程序,使用Angular2作为前端,cakephp 3作为REST Api,身份验证工作正常,但是当我尝试访问任何其他url时,我得到了401 Unauthorized状态,我注意到请求方法是选项,而不是我在代码中使用的get,并且带有我的令牌的授权头不会发送到服务器: 这是我的user.service.ts代码: constructor(private http: Http, private router: Router, ) { } login(em

我试图创建一个应用程序,使用Angular2作为前端,cakephp 3作为REST Api,身份验证工作正常,但是当我尝试访问任何其他url时,我得到了401 Unauthorized状态,我注意到请求方法是选项,而不是我在代码中使用的get,并且带有我的令牌的授权头不会发送到服务器:

这是我的user.service.ts代码:

constructor(private http: Http,
          private router: Router,
) { }

login(email: string, password: string){
    let headers: Headers = new Headers({ 'Accept': 'application/json','Content-Type': 'application/json' });
    let options: RequestOptions = new RequestOptions({headers: headers});

    return this.http.post('http://www.students.com/api/users/token.json', {email: email, password: password}, options)
  .map((data: Response)=> data.json())
  .subscribe(
    (data)=> this.handlData(data),
    (error)=> this.handlError(error)
  );
}

getSessionData(){
    let token = localStorage.getItem('usr_token');
    let headers = new Headers({ 'Accept': 'application/json', 'Authorization': 'Bearer ' + token });
    let options: RequestOptions = new RequestOptions({headers: headers});

    return this.http.get('http://www.students.com/api/users/getSessionData', options).subscribe(
       data => console.log(data),
       err => console.log(err)
     );
}

handlData(data){

    if(data.success){
        let usrData = data.data.user;
        this.user = new User(usrData.email, usrData.firstname, usrData.lastname, usrData.role, data.data.token);
        localStorage.setItem('id_token', data.data.token);
    }
}

handlError(error){
   console.log(error);
}
我尝试使用angular2 jwt模块,但我遇到了相同的错误,为了确保我的API工作正常,我使用Postman chrome扩展对其进行了测试,结果如预期所示:

这是我的Apache2虚拟主机配置

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html/students
    ServerName www.students.com
    <Directory /var/www/html/students>                        
        Require all granted  
        Options Indexes FollowSymLinks Includes
        AllowOverride all
    </Directory>
    Header always set Access-Control-Allow-Origin "*"                   
    Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS"
    Header always set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization"
</VirtualHost>

服务器管理员webmaster@localhost
DocumentRoot/var/www/html/students
服务器名www.students.com
要求所有授权
选项索引和以下符号链接包括
允许超越所有
标题始终设置访问控制允许原点“*”
标头始终设置访问控制允许方法“POST、GET、OPTIONS”
Header始终设置访问控制允许Header“来源、X请求、内容类型、接受、授权”

有人有同样的问题吗?知道为什么会这样吗?

这不是Angular的问题,而是后端的问题。Angular试图通过检查服务器是否在选项请求中返回OK来发出飞行前请求。您应该将后端设置为对选项请求响应200或204

如果您使用的是node.js:

app.use('/api', (req, res, next) => {
    /** Browser check for pre-flight request to determine whether the server is webdav compatible */
    if ('OPTIONS' == req.method) {
        res.sendStatus(204);
    }
    else next();
});
或laravel(PHP):

这将告诉浏览器服务器可以适当地处理webdav请求方法

更新:由asker在CakePHP上添加:

public function initialize() {
    parent::initialize();

    if($this->request->is('options')) {
        $this->response->statusCode(204);
        $this->response->send();
        die();
    }

    $this->Auth->allow(['add', 'token']);
}

你有没有看过谢谢你的快速回复,很遗憾我已经看过了,但是没有太感谢你,现在我明白了为什么会发生这种情况,所以如果有人在Cakephp3中遇到同样的问题,我就是这样解决问题的:
public function initialize(){parent::initialize();if($this->request->is('options')){$this->response->statusCode(200);$this->response->send();die();}$this->Auth->allow(['add',token']);}
,但我仍然不明白为什么每次发布或获取之前都会发送选项请求request@yassineelkhanboubiPOST、GET、PUT和类似方法(我认为它们被正确地称为WebDav方法)并不是服务器上的主流。因此浏览器需要向服务器发送“飞行前”选项请求,以确定服务器是否真正支持POST和GET(以及PUT、PATCH等)方法。根据我的经验,我必须在某些服务器环境中执行此操作,但在其他服务器环境中不执行此操作。因此,我认为在服务器级别执行此操作有更合适的方法。我更新了我的答案,将您的解决方案包含在Cake PHP 3中。@yassineelkhanboubi注意到204是一个更适合于空内容的响应代码。非常感谢您的解释更新和更新。
public function initialize() {
    parent::initialize();

    if($this->request->is('options')) {
        $this->response->statusCode(204);
        $this->response->send();
        die();
    }

    $this->Auth->allow(['add', 'token']);
}