2016-12-10 4 views
2

Я пытаюсь создать приложение с использованием Angular2 в качестве интерфейса и cakephp 3 как REST Api, аутентификация работает нормально, но когда я пытаюсь получить доступ к любому другому URL-адресу, я получаю 401 Несанкционированное статус, и я заметил, что метод запроса OPTIONS вместо GET, что я использовал в моем коде, и Авторизация заголовок с моим маркером не отправляется на сервер:Угловая 2 не отправляет заголовок авторизации с использованием аутентификации JWT

enter image description here

Вот мой 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 работает отлично, я проверил его с Почтальон хрома расширение, и она работала, как ожидалось:

enter image description here

и вот моя конфигурация Apache2 VirtualHost

<VirtualHost *:80> 
    ServerAdmin [email protected] 
    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> 

у кого-то была такая же проблема? любые идеи, почему это происходит?

+0

вы смотрели на [этот ответ] (http://stackoverflow.com/a/38186000/2435473) –

+0

спасибо за быстрый ответ , к сожалению, я уже это сделал, но не повезло –

ответ

3

Это не проблема с угловым, а с вашим backend. Угловой пытается выполнить запрос предполетной проверки, проверяя, возвращает ли сервер OK запрос OPTIONS. Вы должны настроить свой сервер для ответа на запросы OPTIONS 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):

App::before(function($request) 
{ 
    // Sent by the browser since request come in as cross-site AJAX 
    // The cross-site headers are sent via .htaccess 
    if ($request->getMethod() == "OPTIONS") 
     return new SuccessResponse(); 
}); 

Это укажет браузеру, что сервер может обрабатывать методы запроса WebDAV надлежащим образом.

UPDATE: добавил Аскер на CakePHP:

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

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

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

Большое спасибо, теперь я понимаю, почему это происходит, поэтому, если у кого-то была такая же проблема в Cakephp3, вот как я решил проблему: 'public function initialize() { родитель :: Initialize(); if ($ this-> request-> is ('options')) { $ this-> response-> statusCode (200); $ this-> response-> send(); die(); } $ this-> Auth-> allow (['add', 'токен']); } ', но я до сих пор не понимаю, почему запрос OPTIONS отправляется перед каждым запросом POST или GET. –

+0

@yassineelkhanboubi. POST, GET, PUT и аналогичные методы (я думаю, что они правильно называются методами WebDav) не были основными на серверах , Поэтому браузеру необходимо отправить запрос «предполетный» OPTIONS на сервер, чтобы определить, действительно ли сервер поддерживает методы POST и GET (и PUT, PATCH и т. Д.). По моему опыту, мне приходилось делать это на некоторых серверных средах, но не на других. Поэтому я думаю, что есть более подходящий способ сделать это на уровне сервера.Я обновил свой ответ, чтобы включить ваше решение с Cake PHP 3. – borislemke

+0

@yassineelkhanboubi отметим, что 204 является более подходящим кодом ответа для пустого контента. – borislemke

Смежные вопросы