Is there anyway to check for user on unprotected route in case they provide the token? The idea is that I want to get user login status everywhere on the site without getting JWT expired / invalid if the requested route is not protected.
Hello,
There are different ways to achieve this, the simplest being to configure the jwt listener (guard authenticator) on the unprotected firewall, beside the anonymous listener, e.g:
security:
# ...
firewalls:
secure:
pattern: ^/api
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
unsecure:
pattern: ^/unsecure
anonymous: true
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
# You may have the form login on this one
#form_login:
# check_path: /login
# require_previous_session: false
# success_handler: lexik_jwt_authentication.handler.authentication_success
# failure_handler: lexik_jwt_authentication.handler.authentication_failure
access_control:
- { path: ^/unsecure, roles: [IS_AUTHENTICATED_ANONYMOUSLY, IS_AUTHENTICATED_FULLY] }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
If a valid token is passed, you'll be able to retrieve the user from the controller of your unprotected route through $this->getUser(), if no token was passed, it will be null.
One thing to be aware of: If someone sends an invalid token to your unprotected route, he will get a 401 failure response as for the secured firewall (exceptions are thrown even if you allows anonymous, invalid credentials should never be passed).
Hope this helps you.
I actually tried that solution but getting 401 is pretty undesirable since what I want is either null user / anon or user with correct credential to render the page.
You should have a look at https://github.com/lexik/LexikJWTAuthenticationBundle/issues/298, we give a trick to change this behavior. It will be documented soon
It works but it's kind of hacky IMO although i have only skimped through the spec so i'm unsure, or maybe it's how symfony normally works? I don't have much experience in symfony anyhow. Thanks for answering me.
Yeah, the authentication fails at the first exception thrown no matter if the current firewall allows anonymous requests or not, there's no built-in way to bypass that.
You're welcome.
I think i found a solution to handle a request on an unprotected route when the client sends an expired token.
@security.access_map as argumentYou can also extend this example by checking if the token is valid and only abort the authenticator when the token is invalid.
The benefit from this solution is not to separate your api endpoints by secure and public access.
The solution in #298 does not work to handle this problem. The code example also does not work in SF4.
public function supports(Request $request)
{
$supports = $this->decorated->supports($request);
list($accessMap) = $this->accessMap->getPatterns($request);
if (is_array($accessMap) && in_array('IS_AUTHENTICATED_ANONYMOUSLY', $accessMap, true)) {
$supports = false;
}
return $supports;
}
Most helpful comment
Hello,
There are different ways to achieve this, the simplest being to configure the jwt listener (guard authenticator) on the unprotected firewall, beside the
anonymouslistener, e.g:If a valid token is passed, you'll be able to retrieve the user from the controller of your unprotected route through
$this->getUser(), if no token was passed, it will be null.One thing to be aware of: If someone sends an invalid token to your unprotected route, he will get a 401 failure response as for the secured firewall (exceptions are thrown even if you allows anonymous, invalid credentials should never be passed).
Hope this helps you.