如何解决 Symfony3 中的 ServiceNotFoundException

Posted

技术标签:

【中文标题】如何解决 Symfony3 中的 ServiceNotFoundException【英文标题】:How to solve ServiceNotFoundException in Symfony3 【发布时间】:2018-02-15 22:54:25 【问题描述】:

错误

 ServiceNotFoundException in CheckExceptionOnInvalidReferenceBehaviorPass.php 
 The service "token_authenticator" has a dependency on a non-existent service "lexik_jwt_authentication.jwt_encoder".

我需要什么

我需要使用 symfony 验证 angular2 应用程序。

config.yml

lexik_jwt_authentication:
private_key_path: '%kernel.root_dir%/../var/jwt/private.pem'
public_key_path:  '%kernel.root_dir%/../var/jwt/public.pem'
pass_phrase:      '%jwt_key_pass_phrase%'
token_ttl: 3600

security.yml

 firewalls:
    main:
        pattern: ^/
        logout:       true
        anonymous:    true
        stateless: true

        guard:
            authenticators:
                - 'token_authenticator'

services.yml

 services:

 token_authenticator:
    class: AcmeStoreBundle\Security\TokenAuthenticator
    arguments: ['@lexik_jwt_authentication.jwt_encoder', '@doctrine_mongodb']

routing.yml

 acme_store_login_user:
   type: rest
   path:     /login_check
   defaults:  _controller: AcmeStoreBundle:Login:login 
name_prefix:  api_

登录控制器代码

  public function loginAction(Request $request) 

   $data = json_decode(file_get_contents('php://input'), true);
    $userName = $data['username'];
    $password = $data['password'];

    $user = $this->get('doctrine_mongodb')
            ->getRepository('AcmeStoreBundle:User')
            ->findOneBy(['username' => $userName]);

    if (!$user) 
        throw $this->createNotFoundException();
    

    $isValid = $this->get('security.password_encoder')
            ->isPasswordValid($user, $password);

    if (!$isValid) 
        throw new BadCredentialsException();
    

    $response = new Response(Response::HTTP_OK);
    $token = $this->getToken($user);

    $response = new Response($this->serialize(['token' => $token]), Response::HTTP_OK);
    return $this->setBaseHeaders($response);



public function serialize($data) 
    $context = new SerializationContext();
    $context->setSerializeNull(true);

    return $this->get('jms_serializer')
                    ->serialize($data, 'json', $context);


public function getToken(User $user) 

    return $this->container->get('lexik_jwt_authentication.encoder')
                    ->encode([
                        'username' => $user->getUsername(),
                        'exp' => time() + 3600 ,
    ]);

参考:

https://github.com/chalasr/lexik-jwt-authentication-sandbox https://knpuniversity.com/screencast/symfony-rest4/create-json-web-token#play

谁能建议我如何解决这个问题。

【问题讨论】:

您使用的是哪个版本的 LexikJWTAuthenticationBundle? 如您所见,我已从以上 2.0 版以上的链接中获得参考 【参考方案1】:

您使用的是 2.x 版本,其中(从更改日志中可以看到)lexik_jwt_authentication.jwt_encoder 服务(来自 1.x 版本)不再存在。你应该使用lexik_jwt_authentication.encoder.default:

服务 lexik_jwt_authentication.jwt_encoder 已在 喜欢 lexik_jwt_authentication.encoder.default 支持 OpenSSL 和 phpseclib 加密引擎。

 token_authenticator:
    class: Acme\StoreBundle\Security\TokenAuthenticator
    arguments: ['@lexik_jwt_authentication.encoder.default', '@doctrine_mongodb']

【讨论】:

现在我遇到了新问题尝试从命名空间“AcmeStoreBundle\Security”加载类“TokenAuthenticator”。您是否忘记了另一个命名空间的“使用”语句? 发布AcmeStoreBundle/Security/TokenAuthenticator.php文件 我已经上传了完整的文件地址s000.tinyupload.com/?file_id=06840239099356572314 您使用了错误的命名空间。另外,将代码粘贴到您的问题中。 你能在代码 sn-p 中建议它关于实体管理器 orm:mysql.but 我需要 mongo db 所以尝试使用 DoctrineMongoDB;公共函数 __construct(JWTEncoderInterface $jwtEncoder, DoctrineMongoDB $em) $this->jwtEncoder = $jwtEncoder; $this->em = $em; 【参考方案2】:

我在 Symfony 4 上遇到了同样的问题,因为我的 LoginConroller 扩展了 BaseController,所以请确保您的 LoginController 扩展了 Controller Class。像这样:

class LoginController extends Controller 
  .......

【讨论】:

以上是关于如何解决 Symfony3 中的 ServiceNotFoundException的主要内容,如果未能解决你的问题,请参考以下文章

在 Kubernetes Ingress 从 v1beta1 切换到 v1 时出现错误“io.k8s.api.networking.v1.IngressBackend”中的“未知字段“serviceN

Behat 与 Symfony3 不兼容?

Symfony 3,一个应用程序中的 2 个防火墙

Symfony3 表单组件试图将 null 传递给 PHP 7 中的类型提示方法

无法找到模板symfony3

从 Symfony3 中经过身份验证的用户 (HWIOAuth) 获取 Angular2 中的 JWT 令牌