How to restfully login, Symfony2 Security, FOSUserBundle, FOSRestBundle?
Solution 1
There are many ways to provide authentication and authorization to a REST Web Service but the most accepted one seems to be OAuth. Facebook, Twitter, Google, Github and the like use it.
The people at Friends Of Symfony has a bundle to implement OAuth authentication and authorization on Symfony2: https://github.com/FriendsOfSymfony/FOSOAuthServerBundle and I think this is what you are looking for.
EDIT: For more information on Oauth, the people at Cloudfoundry posted an interesting article a couple of days ago.
About other options you can use, a simple one is basic authentication:
firewalls:
main:
pattern: ^/rest
anonymous: ~
form_login: false
provider: fos_user_bundle
http_basic:
realm: "REST Service Realm"
EDIT2: As I see that there is still people voting this answer I think that it is needed to note that at the time of writing this answer JWT was not an option yet, but that maybe it is a better option than OAuth on some use cases (e.g. When the API is going to be consumed by your own apps). So here is a link to a good JWT implementation for Symfony2/3: https://github.com/lexik/LexikJWTAuthenticationBundle/blob/master/Resources/doc/index.md
Solution 2
You should not use CURL to authenticate the user with your web service.
Take a look into ResettingController.php (in FOSUserBundle/Controller) and LoginManager.php (in Security), there is an example how to authenticate the user using Symfony Security :
Controller/ResettingController.php
/**
* Authenticate a user with Symfony Security
*
* @param \FOS\UserBundle\Model\UserInterface $user
* @param \Symfony\Component\HttpFoundation\Response $response
*/
protected function authenticateUser(UserInterface $user, Response $response)
{
try {
$this->container->get('fos_user.security.login_manager')->loginUser(
$this->container->getParameter('fos_user.firewall_name'),
$user,
$response);
} catch (AccountStatusException $ex) {
// We simply do not authenticate users which do not pass the user
// checker (not enabled, expired, etc.).
}
}
and in Security/LoginManager.php
final public function loginUser($firewallName, UserInterface $user, Response $response = null)
{
$this->userChecker->checkPostAuth($user);
$token = $this->createToken($firewallName, $user);
if ($this->container->isScopeActive('request')) {
$this->sessionStrategy->onAuthentication($this->container->get('request'), $token);
if (null !== $response) {
$rememberMeServices = null;
if ($this->container->has('security.authentication.rememberme.services.persistent.'.$firewallName)) {
$rememberMeServices = $this->container->get('security.authentication.rememberme.services.persistent.'.$firewallName);
} elseif ($this->container->has('security.authentication.rememberme.services.simplehash.'.$firewallName)) {
$rememberMeServices = $this->container->get('security.authentication.rememberme.services.simplehash.'.$firewallName);
}
if ($rememberMeServices instanceof RememberMeServicesInterface) {
$rememberMeServices->loginSuccess($this->container->get('request'), $response, $token);
}
}
}
$this->securityContext->setToken($token);
}
Trent
Updated on June 09, 2020Comments
-
Trent almost 4 years
I'd like to be able to login via a ws.
I've tried to simulate this with curl pointing to
/login
but it only handles HTML, etc. By the way, it requires a CSRF which I don't want.So I'd like to either disable the CRSF (from the
login_check
) or find a way to do it myself.Can I override the LoginListener (where is it?) which is used when the route
login_check
is catched.ANy clues?
-
thenetimp over 9 yearsOauth is only necessary when you are creating an API for 3rd parties to authenticate against your API. If his API is only being used by his application oAuth is overkill and http basic over SSL is more then sufficient.
-
adosaiguas over 9 years@thenetimp well, that is not 100% true. Although I agree that in many cases basic auth over SSL is enough (That's why I also added it), ouath is not only useful when 3rd parties are going to use your API, but also when your own apps (mobile, web, etc...) are going to use it (see the different grant types). Another method can be to use authentication tokens.
-
thomaskonrad almost 7 yearsDon't use JWT or OAuth for sessions. As @thenetimp said, these technologies are made for 3rd-party authentication or single sign-on. See cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions.