2
votes

I am working on an API in symfony that uses JWT for authentication. For JWT i use LexikJWTAuthenticationBundle and for token refreshment i use JWTRefreshTokenBundle. What i want to do is to authenticate user via token and give it refresh token. In security i have:

firewalls:
        # disables authentication for assets and the profiler, adapt it according to your needs
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

        login:
            pattern:    ^/api/login_check
            stateless:  true
            anonymous:  true
            form_login:
                check_path:               fos_user_security_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
        register:
            pattern:    ^/api/register
            anonymous:  true
            stateless:  true
        refresh:
            pattern:    ^/api/token/refresh
            stateless:  true
            anonymous:  true
        api:
            pattern:    ^/api
            provider:   fos_userbundle
            stateless:  true
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator

And inside my registration action i have:

    /**
     * @Route("/api/register")
     * @Method({"POST"})
     */
    public function registerAction(Request $request)
    {
        $userManager = $this->get('fos_user.user_manager');
        $data = $request->request->all();

        $mailValidator = $this->get('validator.email');
        $mailValidator->validate($data['email']);

        $user = $userManager->createUser();
        $user->setUsername($data['username']);
        $user->setPlainPassword($data['password']);
        $user->setEmail($data['email']);
        $user->setEnabled(true);

        $userManager->updateUser($user);

        return $this->generateToken($user, 201);
    }

    protected function generateToken(User $user, $statusCode = 200)
    {
        $token = $this->get('lexik_jwt_authentication.jwt_manager')->create($user);
        $response = array(
            'token' => $token,
            'refreshToken' => null,
            'username'  => $user->getUsername(),
            'mail'      => $user->getEmail(),
        );

        return new JsonResponse($response, $statusCode);
    }

Inside generate action method i can create token from user entity, but i can't manage to create refresh token also. For provider i use FOSUserBundle, and it's login_check controller. I've tried to send post request to that controller from generateToken method, but didn't succeed. Any help would be appreciated.

1
Me too. Have you found a solution to this?Ernest Boabramah

1 Answers

-1
votes

I don't know if you solved it but the refresh token will be generated after successful login. So you do not need to generate a refresh token when registration. This is my code :

Security.yml:

security:
encoders:
    FOS\UserBundle\Model\UserInterface: bcrypt

role_hierarchy:
    ROLE_ADMIN:       ROLE_USER
    ROLE_SUPER_ADMIN: ROLE_ADMIN

providers:
    fos_userbundle:
        id: fos_user.user_provider.username_email

firewalls:
    login:
        pattern:    ^/login_check
        stateless:  true
        anonymous:  true
        form_login:
            check_path:               fos_user_security_check
            success_handler:          lexik_jwt_authentication.handler.authentication_success
            failure_handler:          lexik_jwt_authentication.handler.authentication_failure
            require_previous_session: false
    register:
        pattern:    ^/register
        anonymous:  true
        stateless:  true
    refresh:
        pattern:    ^/token/refresh
        stateless:  true
        anonymous:  true
    api:
        pattern:    ^/
        provider:   fos_userbundle
        stateless:  true
        guard:
                authenticators:
                    - 'token_authenticator'

access_control:
    - { path: ^/token/refresh, roles: IS_AUTHENTICATED_ANONYMOUSLY }

Service.yml:

services:
token_authenticator:
    class: UserBundle\Security\TokenAuthenticator
    arguments: ['@lexik_jwt_authentication.encoder', '@doctrine.orm.entity_manager']

config.yml:

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%'

gesdinet_jwt_refresh_token:
    user_provider: fos_user.user_provider.username_email
    ttl: 2592000
    ttl_update: true
    firewall: api

Run in terminal:

curl -X POST http://demowebsite.com/login_check -d username=USERNAME -d password=PASSWORD

This wil generate a token and refresh token. The refresh token will be stored in your DB table refresh_token