2017-10-27 18 views
2

私は単純なcakephpバックエンドを作成しています。フロントエンドの場合、私は角度を使用しています。 Angularはapiルート(ADmad JWTプラグインを使用)をバックエンドに接続し、ログインしてトークンを取得する必要があります。角度JWT認証 - 常に401が無認可

私の今、私はそれが動作します(以下のオプション付き)ポストマン、と私の接続をテストしたいときApi/UsersController.php

public function token() 
{ 
    $user = $this->Auth->identify(); 
    if (!$user) { 
     throw new UnauthorizedException('Invalid username or password'); 
    } 
    $this->set([ 
     'success' => true, 
     'data' => [ 
      'token' => JWT::encode(
       [ 
        'sub' => $user['id'], 
        'exp' => time() + 604800 
       ], 
       Security::salt() 
      ) 
     ], 
     '_serialize' => ['success', 'data'] 
    ]); 
} 

Request-Type: POST 
URL:   http://cake3api.app/api/users/token.json 
Headers:  Accept  => application/vnd.api+json 
       Content-Type => application/vnd.api+json 
Body (JSON array): 
{ 
    "username":"test", 
    "password":"1234" 
} 

回答:

{ 
    "success": true, 
    "data": { 
     "token": "HERE_COMES_THE_TOKEN_AS_ANSWER" 
     } 
} 

今I Angular4でこのauth-apiを使用したい、私は以下の受信

import { Injectable } from '@angular/core'; 
import { Headers, Http } from '@angular/http'; 
import 'rxjs/add/operator/toPromise'; 

@Injectable() 
export class AuthService { 

    private BASE_URL: string = 'http://cake3api.app/api/users'; 
    private headers: Headers = new Headers({ 
     'Content-Type' : 'application/vnd.api+json', 
     'Accept' : 'application/vnd.api+json' 
    }); 

    constructor(private http: Http) { } 

    login(user): Promise<any> { 
     let url: string = `${this.BASE_URL}/token.json`; 
     return this.http.post(url, user, {headers: this.headers}).toPromise(); 
    } 
} 

そして、私はこれで私のLoginComponent

import { Component, OnInit } from '@angular/core'; 
import { AuthService } from '../../services/auth.service'; 

@Component({ 
    selector: 'app-login', 
    templateUrl: './login.component.html', 
    styleUrls: ['./login.component.css'] 
}) 

export class LoginComponent implements OnInit { 

    constructor(private auth: AuthService) { } 

    ngOnInit(): void { 
     let sampleUser: any = { 
      username: 'test' as string, 
      password: '1234' as string 
     }; 

     this.auth.login(sampleUser).then((user) => { 
      console.log(user.json()); 
     }).catch((err) => { 
      console.log(err); 
     }); 
    } 

} 

でサービスを呼んでいる:私はAuthServiceを作成したので、私はケーキ-APIへの約束をすることができます

OPTIONS http://cake3api.app/api/users/token.json 401 (Unauthorized) 

http://cake3api.app/api/users/token.jsonの読み込みに失敗しました: プリフライトの応答が無効なHTTPを持っていますステータスコード401

// XHR Request & Response (from console) 
**GENERAL** 
Request URL:http://cake3api.app/api/users/token.json 
Request Method:OPTIONS 
Status Code:401 Unauthorized 
Remote Address:127.0.0.1:80 
Referrer Policy:no-referrer-when-downgrade 

**RESPONSE HEADERS** 
Access-Control-Allow-Headers:origin, x-requested-with, content-type 
Access-Control-Allow-Methods:PUT, GET, POST, DELETE, OPTIONS 
Access-Control-Allow-Origin:* 
Connection:Keep-Alive 
Content-Length:247 
Content-Type:application/json; charset=UTF-8 
Date:Fri, 27 Oct 2017 08:56:17 GMT 
Keep-Alive:timeout=5, max=100 
Server:Apache/2.4.27 (Win32) OpenSSL/1.0.2l PHP/7.1.9 
X-DEBUGKIT-ID:ac7b0f38-4c97-44d4-8c26-9f95b94ce937 
X-Powered-By:PHP/7.1.9 

**REQUEST HEADERS** 
Accept:*/* 
Accept-Encoding:gzip, deflate 
Accept-Language:de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4,bs;q=0.2 
Access-Control-Request-Headers:content-type 
Access-Control-Request-Method:POST 
Cache-Control:no-cache 
Connection:keep-alive 
Host:cake3api.app 
Origin:http://localhost:4200 
Pragma:no-cache 
Referer:http://localhost:4200/login 
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36 

誰もがアイデア、なぜこの星座が動作していないのですか?私の考えは、その角度が要求を送信していないということです(間違ったヘッダーが送信されましたか?)。奇妙なことは、私の郵便配達員とのテストは機能していたが、角度のないテストではなかったということだ。

ケーキがORIGINヘッダーを受け入れないためだと誰かが考えた場合、それはすべきです。私はこの問題は-request OPTIONSを送信するブラウザであると思われるので./.htaccess

<IfModule mod_headers.c> 
    Header set Access-Control-Allow-Origin "*" 
    Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type" 
    Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS" 
</IfModule> 

EDIT

だ、私はバイパスを作ったが、それでも動作していないことでアクセス制御を可能にしました。

RewriteEngine On 
RewriteCond %{REQUEST_METHOD} OPTIONS 
RewriteRule ^(.*)$ $1 [R=200,L] 

エラーメッセージは消えますが、新しいものが来た:

http://cake3api.app/api/users/token.jsonの読み込みに失敗しました: プリフライトリクエストへの応答は、アクセス制御チェックに合格しない:いいえ 「アクセス制御は、許可します-Origin 'ヘッダーが要求された リソースに存在します。したがって、「http://localhost:4200」の原点は許可されません。

ここでは、ヘッダAccess-Control-Allow-Originは設定されていません。しかし、私はすでに同じ.htaccessファイルに設定しました。ここではOPTIONS -requestの回避策を適用しました。どのような厄介な問題は、すでにそのような小さなもののために多くの時間を失った...

+0

更新:無効なCORSでChromeを使用すると機能します。 'chrome.exe --user-data-dir =" C:/ ChromeDevSession "--disable-web-security' –

+0

ヘッダーが存在しないと判断された場合、これは正しいと考えられます。サーバーの応答を調べて、ヘッダーが存在するかどうかを確認します。また、CakePHP側でのCORS OPTIONSリクエスト処理の実装については、** https://github.com/snelg/cakephp-cors**と** https://github.com/ozee31/cakephp-cors**をチェックしてください。 – ndm

+0

OPTIONS要求の認証を要求するようにサーバーが誤って構成されています。解決策は、OPTIONS要求の認証を要求しないようにそのサーバーを構成することです。あなたのコードからPOSTを試す前に、あなたのブラウザがCORSプリフライトのOPTIONSリクエストを送信しているので、しかし、あなたのブラウザがそのOPTIONS要求を送るとき、それは(意図的に)要求の資格を含まない。 – sideshowbarker

答えて

0

http://cake3api.app/api/users/token.jsonの読み込みに失敗しました:あなたは郵便配達は、あなたが上記の例外を取得し、ブラウザ経由しながら、サーバから正しい応答を受信することが可能であると述べたよう プリフライトの応答が無効なHTTPステータスコード401

を持っていますこれは基本的な問題が何であるかをすでに説明しています。

プリフライトリクエストは、実際のリクエストの前にブラウザによって行われたHTTP OPTIONタイプのリクエストです。エラーは、明示的にOPTIONリクエストを処理していないことを意味します。

PHPのサーバがOPTION要求を受け入れ、それが

EDITを動作するはずです確認してください:

Header set Access-Control-Allow-Origin "http://localhost:4200" 
ヘッダーのためのアクセス制御 - 許可 - 起源*の代わりにワイルドカードのホストを追加しよう

とchrome開発ツールのHTTPレスポンスヘッダーを確認して、正しいものがあることを確認してください。

enter image description here

+0

私の投稿を更新しました。あなたは私に次のヒントをくれました。私は、目標が残っている段階は1つしかないと思う。 :) –

+0

私の編集をチェック:) – Karim