问题
I provided two versions of the security.yaml
file. The second version according to API Platform documentation. API Platform sends to the creation a custom user provider. For the second option security.yaml
recommended at API Platform docs, I need to create two additional files. I did not attach them to the topic, but will do it if necessary.
But I think that problem it is in JWT.
Environment:
- node v8.9.4
- chrome 64.0.3282.119
- Ubuntu 16.04
- axios version: 0.16.2
- Vue.js 2.4.2
- vue-axios 2.0.2
- api-platform/api-pack: 1.0
- Symfony 4.0.4
User.php
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* @ORM\Table(name="app_users")
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
*/
class User implements UserInterface, \Serializable
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=25, unique=true)
*/
private $username;
/**
* @ORM\Column(type="string", length=64)
*/
private $password;
/**
* @ORM\Column(type="string", length=60, unique=true)
*/
private $email;
/**
* @ORM\Column(name="is_active", type="boolean")
*/
private $isActive;
public function __construct() // add $username
{
$this->isActive = true;
}
public function getUsername()
{
return $this->username;
}
public function getSalt()
{
// you *may* need a real salt depending on your encoder
// see section on salt below
return null;
}
public function getPassword()
{
return $this->password;
}
public function getRoles()
{
return array('ROLE_ADMIN');
}
public function eraseCredentials()
{
}
/** @see \Serializable::serialize() */
public function serialize()
{
return serialize(array(
$this->id,
$this->username,
$this->password,
// see section on salt below
// $this->salt,
));
}
/** @see \Serializable::unserialize() */
public function unserialize($serialized)
{
list (
$this->id,
$this->username,
$this->password,
// see section on salt below
// $this->salt
) = unserialize($serialized);
}
}
First option security.yaml
security:
encoders:
App\Entity\User:
algorithm: bcrypt
providers:
our_db_provider:
entity:
class: App\Entity\User
property: username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/login
stateless: true
anonymous: true
form_login:
check_path: /api/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
provider: our_db_provider
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
Second option security.yaml
security:
encoders:
App\Entity\User:
algorithm: bcrypt
App\Security\User\WebserviceUser: bcrypt
providers:
our_db_provider:
entity:
class: App\Entity\User
property: username
webservice:
id: App\Security\User\WebserviceUserProvider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/api/login
stateless: true
anonymous: true
provider: webservice
form_login:
check_path: /api/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
provider: our_db_provider
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
Headers
curl
curl with headers
In browser
.env
###> lexik/jwt-authentication-bundle ###
# Key paths should be relative to the project directory
JWT_PRIVATE_KEY_PATH=var/jwt/private.pem
JWT_PUBLIC_KEY_PATH=var/jwt/public.pem
JWT_PASSPHRASE=d70414362252a41ce772dff4823d084d
###< lexik/jwt-authentication-bundle ###
lexik_jwt_authentication.yaml
lexik_jwt_authentication:
private_key_path: '%kernel.project_dir%/%env(JWT_PRIVATE_KEY_PATH)%'
public_key_path: '%kernel.project_dir%/%env(JWT_PUBLIC_KEY_PATH)%'
pass_phrase: '%env(JWT_PASSPHRASE)%'
回答1:
Problem be is encrypted private key.
Private key is normally encrypted and protected with a passphrase or password before the private key is transmitted or sent. When you receive an encrypted private key, you must decrypt the private key in order to use the private key.
To identify whether a private key is encrypted or not, open the private key in any text editor. An encrypted key has the first few lines that similar to the following, with the ENCRYPTED word:
---BEGIN RSA PRIVATE KEY---
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,AB8E2B5B2D989271273F6730B6F9C687
------
------
------
---END RSA PRIVATE KEY---
On the other hand, an unecrypted key will have the following format:
---BEGIN RSA PRIVATE KEY---
------
------
------
---END RSA PRIVATE KEY---
Encrypted key cannot be used directly in applications in most scenario. It must be decrypted first.
OpenSSL in Linux is the easiest way to decrypt an encrypted private key. Use the following command to decrypt an encrypted RSA key:
openssl rsa -in ssl.key.secure -out ssl.key
Make sure to replace the “server.key.secure” with the filename of your encrypted key, and “server.key” with the file name that you want for your encrypted output key file.
If the encrypted key is protected by a passphrase or password, enter the pass phrase when prompted.
Once done, you will notice that the ENCRYPTED wording in the file has gone.
If be I did not use Postman, then I would not have seen the error of Symfony, which helped me find the root of the problem. It would be nice if be Lesik LexikJWTAuthenticationBundle processed this error.
回答2:
My solutions was to add this in .htaccess
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
回答3:
I was having trouble with this exact issue and my suggestion is to follow this steps to resolve yours:
- Obtain the token
- Generate the SSH keys : properly
- Send authenticate request using FormData
hope this will solve your problem.
回答4:
Try to regenerate private and public keys with custom passphrase and set it in .env file.
Change login firewall in security.yaml:
...
firewalls
...
login:
pattern: ^/api/login
stateless: true
anonymous: true
provider: our_db_provider
json_login:
check_path: /api/login_check
username_path: username
password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
...
If it doesn't help, try to use FosUserBundle.
In composer.json add:
"friendsofsymfony/user-bundle": "dev-master"
In security.yaml:
...
providers:
...
fos_userbundle:
id: fos_user.user_provider.username
...
firewalls
...
login:
pattern: ^/api/login
stateless: true
anonymous: true
provider: fos_userbundle
json_login:
check_path: /api/login_check
username_path: username
password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
...
See FOSUserBundle Integration in ApiPlatform docs
回答5:
It works for me using this solution
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
回答6:
You need to allow Authorization header either in your project .htaccess file or virtual site configurations (example /etc/apache2/sites-available/000-default.conf)
<Directory your_project_directory>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
Allow from all
Require all granted
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
</Directory>
来源:https://stackoverflow.com/questions/48667976/401-jwt-token-not-found