Symfony 4 API Platform+LexikJWTAuthenticationBundle:凭证错误
Symfony 4 API Platform+LexikJWTAuthenticationBundle : Bad credentials
我正在尝试使用 LexikJWTAuthenticationBundle 创建 JWT 身份验证。
在 http://127.0.0.1:8000/api/
和 http://127.0.0.1:8000/api/login_check?username=****&password=****
上我得到
{
"code": 401,
"message": "Bad credentials"
}
作为回应。
我的 security.yaml 看起来像这样:
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
App\Entity\User:
algorithm: bcrypt
providers:
my_provider:
entity:
class: App\Entity\User
property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/backend/api/login
stateless: true
form_login:
check_path: /backend/api/login_check
username_parameter: _username
password_parameter: _password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
require_previous_session: false
guard:
authenticators:
- App\Security\LoginFormAuthenticator
api:
pattern: ^/api
stateless: true
lexik_jwt: ~
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
routes.yaml是:
api_login_check:
path: api/login_check
lexik_jwt_authentication.yaml:
lexik_jwt_authentication:
secret_key: '%kernel.project_dir%/config/jwt/private.pem' # required for token creation
public_key: '%kernel.project_dir%/config/jwt/public.pem' # required for token verification
pass_phrase: 'pass' # required for token creation, usage of an environment variable is recommended
token_ttl: 86400
Entity/User.php 文件:
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* @ApiResource()
* @ORM\Table(name="user")
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
*/
class User implements UserInterface, \Serializable
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $username;
/**
* @ORM\Column(type="string", length=255)
*/
private $fullname;
/**
* @ORM\Column(type="string", length=255)
*/
private $password;
/**
* @ORM\Column(type="string", length=255)
*/
private $email;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $mobile;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $bild;
/**
* @ORM\Column(type="boolean")
*/
private $status;
/**
* @ORM\Column(type="integer")
*/
private $usergroupid;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $activewidgetid;
public function getId(): ?int
{
return $this->id;
}
public function getUsername(): ?string
{
return $this->username;
}
public function setUsername(string $username): self
{
$this->username = $username;
return $this;
}
public function getFullname(): ?string
{
return $this->fullname;
}
public function setFullname(string $fullname): self
{
$this->fullname = $fullname;
return $this;
}
public function getPassword(): ?string
{
return $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getMobile(): ?string
{
return $this->mobile;
}
public function setMobile(?string $mobile): self
{
$this->mobile = $mobile;
return $this;
}
public function getBild(): ?string
{
return $this->bild;
}
public function setBild(?string $bild): self
{
$this->bild = $bild;
return $this;
}
public function getStatus(): ?bool
{
return $this->status;
}
public function setStatus(bool $status): self
{
$this->status = $status;
return $this;
}
public function setEnabled(bool $enabled): self
{
$this->enabled = $enabled;
return $this;
}
public function setSuperAdmin(bool $enabled): self
{
$this->enabled = $enabled;
return $this;
}
public function getUsergroupid(): ?int
{
return $this->usergroupid;
}
public function setUsergroupid(int $usergroupid): self
{
$this->usergroupid = $usergroupid;
return $this;
}
public function getActivewidgetid(): ?string
{
return $this->activewidgetid;
}
public function setActivewidgetid(?string $activewidgetid): self
{
$this->activewidgetid = $activewidgetid;
return $this;
}
public function getRoles()
{
return array('ROLE_ADMIN');
}
public function getSalt() {}
public function eraseCredentials() {}
public function serialize()
{
return serialize([
$this->id,
$this->username,
$this->password,
$this->email
]);
}
public function unserialize($string)
{
list (
$this->id,
$this->username,
$this->password,
$this->email
) = unserialize($string, ['allowed_classes' => false]);
}
}
我什至无法访问 Swagger,我的 api_platfrom.yaml 看起来像:
# api/config/packages/api_platform.yaml
api_platform:
swagger:
api_keys:
apiKey:
name: Authorization
type: header
密钥也已创建:
有什么建议,解决方案吗?提前致谢
我认为 a 更进了一步。
我将 security.yaml 更改为:
security:
encoders:
App\Entity\User:
algorithm: bcrypt
providers:
entity_provider:
entity:
class: App\Entity\User
property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login
stateless: true
anonymous: true
json_login:
check_path: /login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
register:
pattern: ^/register
stateless: true
anonymous: true
api:
pattern: ^/api
stateless: true
anonymous: false
provider: entity_provider
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/, roles: IS_AUTHENTICATED_FULLY }
现在我对 http://localhost:8000/api/
和 /api/login_check
的回复是
{
"code": 401,
"message": "JWT Token not found"
}
我得到了相同的响应,即使我尝试使用 CURL:
LexikJTW 包之前的 /api 就像这个演示:https://demo.api-platform.com
如何取回 api 平台并获得令牌作为响应?
我 运行 没有想法和选择...
我解决了。
我在 security.yml:
中所做的更改
security:
encoders:
App\Entity\User:
algorithm: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
entity_provider:
entity:
class: App\Entity\User
property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login
stateless: true
anonymous: true
form_login:
check_path: api_login_check
login_path: api_login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
require_previous_session: false
username_parameter: username
password_parameter: password
api:
pattern: ^/api
stateless: true
provider: entity_provider
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/, roles: IS_AUTHENTICATED_FULLY}
现在 localhost:8000/login_check
我可以获得令牌:
之后,当我尝试访问 localhost:8000/api(例如使用 curl -H "Authorization: Bearer [TOKEN]" http://localhost:8000/api)时,我收到错误响应:
{
"code": 401,
"message": "Unable to find key \"username\" in the token payload."
}
但那是另外一回事了。我会将其标记为已解决。希望对大家有帮助。
这是一个对我有用的例子,使用 FOSUserBundle :
security.yaml
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
dev:
pattern: ^/_(profiler|wdt)
security: false
api:
pattern: ^/api/users # protected path
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
main:
stateless: true
anonymous: true
provider: fos_userbundle
json_login:
check_path: /authentication_token
username_path: username
password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
api_plateform.yaml
api_platform:
mapping:
paths: ['%kernel.project_dir%/src/Entity']
# enable_fos_user: true
swagger:
api_keys:
apiKey:
name: Authorization
type: header
routing.yaml
# app/config/routing.yml
fos_user:
resource: "@FOSUserBundle/Resources/config/routing/all.xml"
authentication_token:
path: /authentication_token
methods: ['POST']
lexik_jwt_authentication.yaml
lexik_jwt_authentication:
secret_key: '%kernel.project_dir%/config/jwt/private.pem'
public_key: '%kernel.project_dir%/config/jwt/public.pem'
pass_phrase: 'your pass phrase'
token_ttl: 3600
并确保在 "access_control" 上删除该行:
- { path: ^/api/, roles: IS_AUTHENTICATED_FULLY }
result without token
result with Bearer {your token}
我正在尝试使用 LexikJWTAuthenticationBundle 创建 JWT 身份验证。
在 http://127.0.0.1:8000/api/
和 http://127.0.0.1:8000/api/login_check?username=****&password=****
上我得到
{
"code": 401,
"message": "Bad credentials"
}
作为回应。
我的 security.yaml 看起来像这样:
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
App\Entity\User:
algorithm: bcrypt
providers:
my_provider:
entity:
class: App\Entity\User
property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/backend/api/login
stateless: true
form_login:
check_path: /backend/api/login_check
username_parameter: _username
password_parameter: _password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
require_previous_session: false
guard:
authenticators:
- App\Security\LoginFormAuthenticator
api:
pattern: ^/api
stateless: true
lexik_jwt: ~
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
routes.yaml是:
api_login_check:
path: api/login_check
lexik_jwt_authentication.yaml:
lexik_jwt_authentication:
secret_key: '%kernel.project_dir%/config/jwt/private.pem' # required for token creation
public_key: '%kernel.project_dir%/config/jwt/public.pem' # required for token verification
pass_phrase: 'pass' # required for token creation, usage of an environment variable is recommended
token_ttl: 86400
Entity/User.php 文件:
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* @ApiResource()
* @ORM\Table(name="user")
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
*/
class User implements UserInterface, \Serializable
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $username;
/**
* @ORM\Column(type="string", length=255)
*/
private $fullname;
/**
* @ORM\Column(type="string", length=255)
*/
private $password;
/**
* @ORM\Column(type="string", length=255)
*/
private $email;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $mobile;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $bild;
/**
* @ORM\Column(type="boolean")
*/
private $status;
/**
* @ORM\Column(type="integer")
*/
private $usergroupid;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $activewidgetid;
public function getId(): ?int
{
return $this->id;
}
public function getUsername(): ?string
{
return $this->username;
}
public function setUsername(string $username): self
{
$this->username = $username;
return $this;
}
public function getFullname(): ?string
{
return $this->fullname;
}
public function setFullname(string $fullname): self
{
$this->fullname = $fullname;
return $this;
}
public function getPassword(): ?string
{
return $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getMobile(): ?string
{
return $this->mobile;
}
public function setMobile(?string $mobile): self
{
$this->mobile = $mobile;
return $this;
}
public function getBild(): ?string
{
return $this->bild;
}
public function setBild(?string $bild): self
{
$this->bild = $bild;
return $this;
}
public function getStatus(): ?bool
{
return $this->status;
}
public function setStatus(bool $status): self
{
$this->status = $status;
return $this;
}
public function setEnabled(bool $enabled): self
{
$this->enabled = $enabled;
return $this;
}
public function setSuperAdmin(bool $enabled): self
{
$this->enabled = $enabled;
return $this;
}
public function getUsergroupid(): ?int
{
return $this->usergroupid;
}
public function setUsergroupid(int $usergroupid): self
{
$this->usergroupid = $usergroupid;
return $this;
}
public function getActivewidgetid(): ?string
{
return $this->activewidgetid;
}
public function setActivewidgetid(?string $activewidgetid): self
{
$this->activewidgetid = $activewidgetid;
return $this;
}
public function getRoles()
{
return array('ROLE_ADMIN');
}
public function getSalt() {}
public function eraseCredentials() {}
public function serialize()
{
return serialize([
$this->id,
$this->username,
$this->password,
$this->email
]);
}
public function unserialize($string)
{
list (
$this->id,
$this->username,
$this->password,
$this->email
) = unserialize($string, ['allowed_classes' => false]);
}
}
我什至无法访问 Swagger,我的 api_platfrom.yaml 看起来像:
# api/config/packages/api_platform.yaml
api_platform:
swagger:
api_keys:
apiKey:
name: Authorization
type: header
密钥也已创建:
有什么建议,解决方案吗?提前致谢
我认为 a 更进了一步。
我将 security.yaml 更改为:
security:
encoders:
App\Entity\User:
algorithm: bcrypt
providers:
entity_provider:
entity:
class: App\Entity\User
property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login
stateless: true
anonymous: true
json_login:
check_path: /login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
register:
pattern: ^/register
stateless: true
anonymous: true
api:
pattern: ^/api
stateless: true
anonymous: false
provider: entity_provider
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/, roles: IS_AUTHENTICATED_FULLY }
现在我对 http://localhost:8000/api/
和 /api/login_check
的回复是
{
"code": 401,
"message": "JWT Token not found"
}
我得到了相同的响应,即使我尝试使用 CURL:
LexikJTW 包之前的 /api 就像这个演示:https://demo.api-platform.com
如何取回 api 平台并获得令牌作为响应? 我 运行 没有想法和选择...
我解决了。 我在 security.yml:
中所做的更改security:
encoders:
App\Entity\User:
algorithm: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
entity_provider:
entity:
class: App\Entity\User
property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login
stateless: true
anonymous: true
form_login:
check_path: api_login_check
login_path: api_login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
require_previous_session: false
username_parameter: username
password_parameter: password
api:
pattern: ^/api
stateless: true
provider: entity_provider
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/, roles: IS_AUTHENTICATED_FULLY}
现在 localhost:8000/login_check
我可以获得令牌:
之后,当我尝试访问 localhost:8000/api(例如使用 curl -H "Authorization: Bearer [TOKEN]" http://localhost:8000/api)时,我收到错误响应:
{
"code": 401,
"message": "Unable to find key \"username\" in the token payload."
}
但那是另外一回事了。我会将其标记为已解决。希望对大家有帮助。
这是一个对我有用的例子,使用 FOSUserBundle :
security.yaml
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
providers:
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
dev:
pattern: ^/_(profiler|wdt)
security: false
api:
pattern: ^/api/users # protected path
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
main:
stateless: true
anonymous: true
provider: fos_userbundle
json_login:
check_path: /authentication_token
username_path: username
password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
api_plateform.yaml
api_platform:
mapping:
paths: ['%kernel.project_dir%/src/Entity']
# enable_fos_user: true
swagger:
api_keys:
apiKey:
name: Authorization
type: header
routing.yaml
# app/config/routing.yml
fos_user:
resource: "@FOSUserBundle/Resources/config/routing/all.xml"
authentication_token:
path: /authentication_token
methods: ['POST']
lexik_jwt_authentication.yaml
lexik_jwt_authentication:
secret_key: '%kernel.project_dir%/config/jwt/private.pem'
public_key: '%kernel.project_dir%/config/jwt/public.pem'
pass_phrase: 'your pass phrase'
token_ttl: 3600
并确保在 "access_control" 上删除该行:
- { path: ^/api/, roles: IS_AUTHENTICATED_FULLY }
result without token
result with Bearer {your token}