我只是尝试使用JWT登录创建我的sf3 api,但是我在身份验证方面遇到了一些麻烦。所以这是我的配置和我意识到的一些测试。
security.yml:
security:
firewalls:
login:
pattern: ^/api/auth
stateless: true
anonymous: true
form_login:
check_path: /api/auth/login-check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
require_previous_session: false
api:
pattern: ^/api
stateless: true
lexik_jwt: ~
access_control:
- { path: ^/api/auth, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
路由.yml:
auth:
path: /auth
defaults: { _controller: api.controller.auth:postAction }
methods: [OPTIONS, POST]
api_login_check:
path: /auth/login-check
config.yml:
nelmio_cors:
paths:
'^/api/':
allow_origin: ['*']
allow_headers: ['*']
allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS']
max_age: 3600
当我调试路由时,我收到以下输出:
$ php bin/console debug:router
----------------------------------- ------------------ -------- ------ -----------------------------------
Name Method Scheme Host Path
----------------------------------- ------------------ -------- ------ -----------------------------------
....
api_homepage ANY ANY ANY /api/
auth OPTIONS|POST ANY ANY /api/auth
api_login_check ANY ANY ANY /api/auth/login-check
....
到目前为止一切顺利,现在问题来了。
我设法测试身份验证的返回
$ curl -v -X POST http://api.local/api/auth/login-check -d _username=user -d _password=user
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to api.local (127.0.0.1) port 80 (#0)
> POST /api/auth/login-check HTTP/1.1
> Host: api.local
> User-Agent: curl/7.51.0
> Accept: */*
> Content-Length: 33
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 33 out of 33 bytes
< HTTP/1.1 200 OK
< Server: nginx/1.10.3
< Content-Type: application/json
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Powered-By: PHP/7.1.3
< Set-Cookie: PHPSESSID=c4o6kuelf914gjnq09m38ec0c7; path=/; HttpOnly
< Cache-Control: no-cache, private
< Date: Fri, 12 May 2017 16:37:23 GMT
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, POST, OPTIONS, DELETE, PUT
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: User-Agent,Keep-Alive,Content-Type,Access-Control-Allow-Headers
<
* Curl_http_done: called premature == 0
* Connection #0 to host api.local left intact
{"token":"b2xlc9.......DW6uAwx4"}
太好了,它正在工作!
当我在浏览器中尝试相同的请求时,我在 OPTIONS 方法上收到 404,所以我尝试使用 curl OPTIONS 请求重新创建请求(真的我不知道这是否有任何意义,但我还是尝试了,其中响应:
$ curl -v -X OPTIONS http://api.local/api/auth/login-check -d _username=user -d _password=user
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to api.local (127.0.0.1) port 80 (#0)
> OPTIONS /api/auth/login-check HTTP/1.1
> Host: api.local
> User-Agent: curl/7.51.0
> Accept: */*
> Content-Length: 33
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 33 out of 33 bytes
< HTTP/1.1 404 Not Found
< Server: nginx/1.10.3
< Content-Type: application/json
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Powered-By: PHP/7.1.3
< Cache-Control: no-cache, private
< Date: Fri, 12 May 2017 16:35:49 GMT
<
{"error":{"code":404,"message":"Not Found"}}
* Curl_http_done: called premature == 0
* Connection #0 to host api.local left intact
我的理解是 api 找不到 OPTIONS 方法的路由,我什至尝试将方法:[选项,POST]添加到api_login_check路由但输出相同。
使用和不使用 nelmioCorsBundle 进行测试,输出相同。
我在这里有点迷茫,谁能看出我做错了什么?
谢谢
您的身份验证路由在 routeting.yml 上是/oauth,但您在示例中使用的是/api/auth。我认为您的配置几乎没有错误。
但是您真正的问题是预检,浏览器在请求之前执行此操作,这是您在浏览器上身份验证失败的原因,并且适用于 CURL。
您的应用程序应该响应路由的 OPTIONS 请求,并告诉浏览器允许哪些方法或标头继续,为了实现这一点,NelmioCorsBundle 是最好的。
您需要覆盖所有路由,您的配置仅与/api 路由和您的登录匹配,请尝试nelmio_cors这样的配置。
nelmio_cors:
defaults:
allow_credentials: false
allow_origin: []
allow_headers: []
allow_methods: []
expose_headers: []
max_age: 0
hosts: []
origin_regex: false
paths:
'^/':
allow_origin: ['*']
allow_headers: ['accept', 'authorization', 'content-type']
allow_methods: ['OPTIONS', 'POST', 'PUT', 'PATCH', 'GET', 'DELETE']
max_age: 3600