4

我有一个项目的问题。

我使用 symfony 2.8、sonata-admin、fosuserbundle、fosrestbundle 和 lexikjwtauthbundle。

在这条路线 /api/login_check 上,我可以使用现有的 fosuser 轻松生成令牌。

API登录

但问题是当我想在控制器路由中获取用户时它总是返回 null,我试过:

$this->getUser()
$this->container->get('security.token_storage')->getToken()->getUser()
$this->container->get('security.context')->getToken()->getUser()

有我的 config.yml :

imports:
    - { resource: parameters.yml }
    - { resource: security.yml }
    - { resource: services.yml }
    - { resource: "@AdsElasticSearchBundle/Resources/config/services.yml" }
    - { resource: "@AdsElasticSearchBundle/Resources/config/fos_elastica.yml" }
    - { resource: "@AdsBotcoinBundle/Resources/config/services.yml" }

# Put parameters here that don't need to change on each machine where the app is deployed
# http://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
    locale: en

framework:
    #esi:             ~
    translator:      { fallbacks: ["%locale%"] }
    secret:          "%secret%"
    router:
        resource: "%kernel.root_dir%/config/routing.yml"
        strict_requirements: ~
    form:            ~
    csrf_protection: ~
    validation:      { enable_annotations: true }
    #serializer:      { enable_annotations: true }
    serializer:
        enabled: false
    templating:
        engines: ['twig']
    default_locale:  fr
    trusted_hosts:   ~
    trusted_proxies: ~
    session:
        # handler_id set to null will use default session handler from php.ini
        handler_id:  ~
    fragments:       ~
    http_method_override: true

# Twig Configuration
twig:
    debug:            "%kernel.debug%"
    strict_variables: "%kernel.debug%"
    number_format:
        decimals: 0
        decimal_point: ','
        thousands_separator: ' '

# Doctrine Configuration
doctrine:
    dbal:
        driver:   pdo_mysql
        host:     "%database_host%"
        port:     "%database_port%"
        dbname:   "%database_name%"
        user:     "%database_user%"
        password: "%database_password%"
        charset:  UTF8
        types:
            json: Sonata\Doctrine\Types\JsonType
        # if using pdo_sqlite as your database driver:
        #   1. add the path in parameters.yml
        #     e.g. database_path: "%kernel.root_dir%/data/data.db3"
        #   2. Uncomment database_path in parameters.yml.dist
        #   3. Uncomment next line:
        #path:     "%database_path%"

    orm:
        auto_generate_proxy_classes: "%kernel.debug%"
        naming_strategy: doctrine.orm.naming_strategy.underscore
        auto_mapping: true

# Swiftmailer Configuration
swiftmailer:
    transport: "%mailer_transport%"
    host:      "%mailer_host%"
    username:  "%mailer_user%"
    password:  "%mailer_password%"
    spool:     { type: memory }

sonata_block:
    default_contexts: [cms]
    blocks:
        sonata.admin.block.admin_list:
            contexts:   [admin]

        #sonata.admin_doctrine_orm.block.audit:
        #    contexts:   [admin]

        sonata.block.service.text:
        sonata.block.service.rss:

        # Some specific block from the SonataMediaBundle
        #sonata.media.block.media:
        #sonata.media.block.gallery:
        #sonata.media.block.feature_media:

        # Some block with different templates
        #acme.demo.block.demo:
        #    templates:
        #       - { name: 'Simple', template: 'AcmeDemoBundle:Block:demo_simple.html.twig' }
        #       - { name: 'Big',    template: 'AcmeDemoBundle:Block:demo_big.html.twig' }

sonata_user:
    security_acl: true
    manager_type: orm # can be orm or mongodb

sonata_block:
    blocks:
        #...
        sonata.user.block.menu:    # used to display the menu in profile pages
        sonata.user.block.account: # used to display menu option (login option)
        sonata.block.service.text: # used to if you plan to use Sonata user routes

# app/config/security.yml
security:
    # [...]

    encoders:
        FOS\UserBundle\Model\UserInterface: sha512

    acl:
        connection: default

fos_user:
    db_driver:      orm # can be orm or odm
    firewall_name:  main
    user_class:     Application\Sonata\UserBundle\Entity\User


    group:
        group_class:   Application\Sonata\UserBundle\Entity\Group
        group_manager: sonata.user.orm.group_manager                    # If you're using doctrine orm (use sonata.user.mongodb.group_manager for mongodb)

    service:
        user_manager: sonata.user.orm.user_manager                      # If you're using doctrine orm (use sonata.user.mongodb.user_manager for mongodb)

doctrine:

    dbal:
        types:
            json: Sonata\Doctrine\Types\JsonType

doctrine:
    orm:
        entity_managers:
            default:
                mappings:
                    ApplicationSonataUserBundle: ~
                    SonataUserBundle: ~
                    FOSUserBundle: ~                                    # If SonataUserBundle extends it            

#fos_rest:
#    routing_loader:
#        include_format: false
#    view:
#        view_response_listener: true

fos_rest:
    param_fetcher_listener: true
    body_listener: true
    format_listener: true
    view:
        view_response_listener: 'force'
        formats:
            xml: true
            json : true
        mime_types:
            json: ['application/json', 'application/x-json']
            jpg: ['image/jpeg']
            png: ['image/png']
        templating_formats:
            html: true
        force_redirects:
            html: true
        failed_validation: HTTP_BAD_REQUEST
        default_engine: twig
    routing_loader:
        default_format: json
    serializer:
        serialize_null:  true

jms_serializer:
    handlers:
        datetime:
            default_format: "Y-m-d\\TH:i:sP"
            default_timezone: "UTC"

lexik_jwt_authentication:
    private_key_path: '%jwt_private_key_path%'
    public_key_path:  '%jwt_public_key_path%'
    pass_phrase:      '%jwt_key_pass_phrase%'
    token_ttl:        '%jwt_token_ttl%'
    # key under which the user identity will be stored in the token payload
    user_identity_field: username
     # token encoding/decoding settings
    encoder:
        # token encoder/decoder service - default implementation based on the namshi/jose library
        service:            lexik_jwt_authentication.encoder.default
        # crypto engine used by the encoder service
        crypto_engine:  openssl
        # encryption algorithm used by the encoder service
        signature_algorithm: RS256

    # token extraction settings
    token_extractors:
        authorization_header:      # look for a token as Authorization Header
            enabled: true
            prefix:  Bearer
            name:    Authorization
        cookie:                    # check token in a cookie
            enabled: true
            name:    BEARER
        query_parameter:           # check token in query string parameter
            enabled: true
            name:    bearer

nelmio_cors:
        defaults:
            allow_credentials: false
            allow_origin: []
            allow_headers: []
            allow_methods: []
            expose_headers: []
            max_age: 0
            hosts: []
            origin_regex: false
            forced_allow_origin_value: ~
        paths:
            '^/api/':
                allow_origin: ['*']
                allow_headers: ['*']
                allow_methods: ['POST', 'PUT', 'GET', 'DELETE']
                max_age: 3600
            '^/':
                origin_regex: true
                allow_origin: ['^http://localhost:[0-9]+']
                allow_headers: ['X-Custom-Auth']
                allow_methods: ['POST', 'PUT', 'GET', 'DELETE']
                max_age: 3600
                hosts: ['^api\.']

和 security.yml :

# To get started with security, check out the documentation:
# http://symfony.com/doc/current/security.html
security:

    role_hierarchy:
        ROLE_ADMIN:       [ROLE_USER, ROLE_SONATA_ADMIN]
        ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
        SONATA:
            - ROLE_SONATA_PAGE_ADMIN_PAGE_EDIT  # if you are using acl then this line must be commented

    providers:
        #jwt:
        #    lexik_jwt:
        #        class: Application\Sonata\UserBundle\Entity\User
        #chain_provider:
        #    chain:
        #        providers: [in_memory, fos_userbundle]
        fos_userbundle:
            #id: fos_user.user_manager
            id: fos_user.user_provider.username
        #in_memory:
        #    memory:
        #        users:
        #            user:  { password: password, roles: [ 'ROLE_USER' ] }
        #            admin: { password: password, roles: [ 'ROLE_ADMIN' ] }

    encoders:
        FOS\UserBundle\Model\UserInterface: bcrypt

    firewalls:
        # Disabling the security for the web debug toolbar, the profiler and Assetic.
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false

        # -> custom firewall for the admin area of the URL
        admin:
            pattern:            /admin(.*)
            context:            user
            form_login:
                provider:       fos_userbundle
                login_path:     /admin/login
                use_forward:    false
                check_path:     /admin/login_check
                failure_path:   null
                always_use_default_target_path: true
                default_target_path: /admin/dashboard
            logout:
                path:           /admin/logout
                target:         /admin/login
            anonymous:          true

        api_login:
            pattern:  ^/api/login
            stateless: true
            anonymous: false
            #provider:  fos_userbundle
            form_login:
                provider:                   fos_userbundle
                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
                username_parameter: username
                password_parameter: password
            logout: true

        api:
            pattern:   ^/api
            #provider: fos_userbundle
            stateless: true
            lexik_jwt: ~
            guard:
                authenticators: 
                    - lexik_jwt_authentication.jwt_token_authenticator
                    #- ads_elastic_search.jwt_token_authenticator
            #lexik_jwt:
            #    authorization_header:
            #        enabled: true
            #        prefix:  Bearer
            #    query_parameter:
            #        enabled: true
            #        name:    bearer
            #lexik_jwt:
            #    authorization_header:
            #        enabled: true
            #        prefix:  Bearer
            #    query_parameter:      
            #        enabled: false
            #        name:    bearer
            #    throw_exceptions:        true
            #    create_entry_point:      false
            #    authentication_provider: lexik_jwt_authentication.security.authentication.provider

            #guard:
            #    authenticators:
            #        - lexik_jwt_authentication.jwt_token_authenticator

        # -> end custom configuration

        # default login area for standard users

        # This firewall is used to handle the public login area
        # This part is handled by the FOS User Bundle
        main:
            pattern:             .*
            context:             user
            form_login:
                provider:       fos_userbundle
                login_path:     /login
                use_forward:    false
                check_path:     /login_check
                failure_path:   null
            logout:             true
            anonymous:          true        

    access_control:
        # URL of FOSUserBundle which need to be available to anonymous users
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }

        # Admin login page needs to be accessed without credential
        - { path: ^/admin/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/logout$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/login_check$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }

        # Secured part of the site
        # This config requires being logged for the whole site and having the admin role for the admin part.
        # Change these rules to adapt them to your needs
        - { path: ^/admin/, role: [ROLE_ADMIN, ROLE_SONATA_ADMIN] }
        - { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }

        # Api
        - { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api,       roles: IS_AUTHENTICATED_FULLY }
        - { path: ^/api/token/refresh, roles: IS_AUTHENTICATED_ANONYMOUSLY }

例如,使用这条路线和 die(var_dump($this->container->get('security.token_storage')->getToken())) : 路由控制器 但我连接良好:

[2017-03-15 10:14:06] security.INFO: Guard authentication successful! {"token":"[object] (Lexik\\Bundle\\JWTAuthenticationBundle\\Security\\Authentication\\Token\\JWTUserToken: JWTUserToken(user=\"admin\", authenticated=true, roles=\"ROLE_SUPER_ADMIN, ROLE_USER\"))","authenticator":"Lexik\\Bundle\\JWTAuthenticationBundle\\Security\\Guard\\JWTTokenAuthenticator"} []

如果您有任何建议或需要更多信息,没问题。

谢谢,

4

0 回答 0