带有LexikJWTAuthenticationBundle的Symfony3 JWT在Preflight OPTIONS上返回404 [英] Symfony3 JWT with LexikJWTAuthenticationBundle returns 404 on Preflight OPTIONS
问题描述
我正在使用 LexikJWTAuthenticationBundle 并尝试使用从我的Ionic2应用程序发送的凭据生成JWT令牌。
I'm working with the LexikJWTAuthenticationBundle and trying to generate a JWT token with credentials sent from my Ionic2 App.
生成令牌可以与Curl和Postman一起使用。
Generating the token works fine with Curl and with Postman.
curl -X POST http://localhost:8000/api/login_check -d _username=root -d _password=root
但是,Ionic2在实际发送带有凭据的POST请求之前发送预检OPTIONS请求。这被Symfony3误解并发回404.
However, Ionic2 sends a preflight OPTIONS request before actually sending the POST request with the credentials. This is misunderstood by Symfony3 and sends back a 404.
来自Ionic2的控制台错误:
选项 http:// localhost:8000 / api / login_check 404(未找到)
XMLHttpRequest无法加载 http:// localhost:8000 / api / login_check 。
OPTIONS http://localhost:8000/api/login_check 404 (Not Found) XMLHttpRequest cannot load http://localhost:8000/api/login_check.
对预检请求的响应未通过访问控制检查:否
'Access-Control-Allow-Origin'标头出现在请求的$上b $ b资源。因此,不允许
访问来源' http:// localhost:8100 '。响应的HTTP状态代码为404.
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access. The response had HTTP status code 404.
0 - {isTrusted:true}
0 - {"isTrusted":true}
EXCEPTION:0 - {isTrusted:true}
EXCEPTION: 0 - {"isTrusted":true}
问题:
什么必须我更改了我的Symfony3应用程序(可能是我的routing.yml或security.yml中的内容),不发回404?
Question:
What must I change in my Symfony3 Application (maybe something in my routing.yml or security.yml) to not send back a 404?
Ionic2 HttpService:
@Injectable()
export class HttpService {
private baseUrl: string = "http://localhost:8000";
constructor(private http: Http){
}
public create<T>(url: string, extractData, data: any = null): Observable<Array<T>>{
let headers = new Headers({ 'Content-Type': 'application/json'});
let options = new RequestOptions({ headers: headers });
return this.http
.post(this.baseUrl + url, data, options)
.map(extractData)
.catch(this.handleError)
}
//More methods here...
}
Symfony routing.yml:
Symfony routing.yml:
api_login_check:
path: /api/login_check
# This line is something I added to see if OPTIONS would work
# However, it did not work.
methods: [POST, OPTIONS]
类似的问题:
推荐答案
说明:
所以完整之后在这个问题上打破了我的头脑,我找到了解决方案。虽然可以合并 NelmioCorsBundle (不确定它是否支持Symfony3),但我发现它只是为了绕过它Cors问题。
Explanation:
So after a full day of breaking my head open on this issue, I found a solution. While it is possible incorporate the NelmioCorsBundle (unsure if it supports Symfony3), I find it overkill just to bypass the Cors problem.
在真实世界的手机应用程序中,不会发送OPTIONS预检请求。这只发生在离子服务
(根据我的理解)。
In a real world phone application, there won't be an OPTIONS preflight request sent. This only occurs for ionic serve
(from what I understood).
想法是建立一个代理服务器对于Ionic2 ..说起来容易做起来难。关于它似乎有很多问题。我已经能够让它工作了。
The idea is to set up a Proxy Server for Ionic2.. easier said than done. There seems to be a lot of issues regarding it. I've been able to get it working though.
应该有 ionic.config.json
在Ionic2项目的根目录下。你只需要添加几行:
There should be an ionic.config.json
at the root directory of your Ionic2 project. You just need to add a few lines:
{
"name": "websurgapp",
"app_id": "",
"v2": true,
"typescript": true,
//This is what I added.
"proxies": [{
"path": "*/api", //<- NOTICE THE */ !
"proxyUrl": "http://localhost:8000/api"
}]
}
然后简单地发送请求:
HttpService:
@Injectable()
export class HttpService {http://localhost:8000;
constructor(private http: Http){
}
public create<T>(url: string, data: any = null, contentType: string = 'application/json'): Observable<Array<T>>{
let headers = new Headers({ 'Content-Type': contentType});
let options = new RequestOptions({ headers: headers });
console.log(data);
return this.http
.post(url, data, options)
.map((res:Response)=>res.json())
.catch(this.handleError)
}
}
AuthService:
@Injectable()
export class AuthService {
constructor(public httpService: HttpService) {
console.log('Hello AuthService Provider');
}
private currentUser: User;
public login(credentials): any {
console.log("Login called.");
//TODO: Upgrade symfony to 3.3 to be able to use JSON.
let body = new URLSearchParams();
body.append('_username', credentials._username);
body.append('_password', credentials._password);
let result = this.httpService.create("/api/login_check", body, 'application/x-www-form-urlencoded');
return result;
}
}
注意我不发送JSON请求。捆绑包当前不支持它。但是,symfony版本3.3。(我在3.1。上)支持它。
- 我的symfony应用程序在
http:// localhost:8000
$上运行b $ b - 我的Ionic 2应用程序运行在
http:// localhost:8100
- My symfony app runs on
http://localhost:8000
- My Ionic 2 app runs on
http://localhost:8100
"path": "*/api"
简单地说明,我们发出的任何碰巧有/ api /的请求都将被转换为proxyUrl。
Simply states that whatever request we send out that happens to have a "/api/" in it will be converted to the proxyUrl.
例如,要生成令牌,我需要将我的凭据发送到/ api / login_check
。
For example, to generate a token, I need to send my credentials to "/api/login_check"
.
我之前尝试的内容:
我之前一直在发送请求 http:// localhost:8000 / api / login_check
,当然会发送预检OPTIONS请求,导致一大堆错误。
I had previously been sending the request to http://localhost:8000/api/login_check
, which of course would send a preflight OPTIONS request causing a whole bunch of errors.
然后我尝试简单地指定/ api / login_check,但http请求会添加http:// localhost:8100
infront .. my应用程序向自己发送请求..这当然不起作用。
I then tried specifiying simply "/api/login_check", but the http request would add "http://localhost:8100"
infront.. my app sending a request to itself.. which of course didn't work.
解决方案解释:
在代理服务器启动的情况下,我只需向/ api / login_check
发送请求,而不会发生任何事情,并将其发送到我的symfony3应用程序一个 POST请求
,没有任何预检OPTIONS请求。
With the proxy server up, I simply send a request to "/api/login_check"
without anything infront, and it gets sent to my symfony3 application as a POST request
without any preflight OPTIONS request.
这篇关于带有LexikJWTAuthenticationBundle的Symfony3 JWT在Preflight OPTIONS上返回404的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!