I’m developing a javascript spa in vue.js which is going to eventually be a cordova application. As well as a backend api built with lumen.
I’m trying to provide login with facebook and google functionality. I’ve added the laravel socialite package and created a redirect and callback route. Ive created a page in my spa with the login buttons that direct to my api redirect. The user is redirected to facebook’s oauth mechanism I login, the callback routes handle function looks something like this
public function handleProviderCallback($provider)
{
$oauthUser = $this->socialiteManager->with($provider)->stateless()->user();
$userEntity = $this->repository->findOrCreateOauthUser($oauthUser);
$providerEntity = app()
->make('em')
->getRepository('EntitiesSocialProvider')
->findOneBy(['name' => $provider]);
if(is_null($providerEntity))
{
throw new Exception('Oauth Provider not found');
}
$socialAccountEntity = app()
->make('em')
->getRepository('EntitiesSocialSocialAccount')
->findOrCreateSocialAccount($providerEntity, $oauthUser, $userEntity);
$token = $this->auth->fromUser($userEntity);
$resource = $this->item($token)
->transformWith($this->transformer)
->serializeWith(new ArraySerialization())
->toArray();
return $this->showResponse($resource);
}
It basically gets a the oauth user, finds or stores them in the database, finds or stores their social account info,
$token = $this->auth->fromUser($userEntity);
Then authenticates them with JWT issuing a token. Which is then serialised and returned as a json response.
The problem is that the response is given while on the backend application, im never returned back to the javascript SPA.
Instead of returning json I could do some redirect like
return redirect()->to('/some-spa-callback-route');
But should the api be aware of the SPA location? and how will this work when the SPA is ported into cordova, as the mobile application wont have a url?
My thoughts are that A
The social provider should redirect directly to the SPA at which point it should make another request exchanging the authorisation code for a JWT token.
B it redirects to the SPA with a query string containing the token, which doesn’t sound secure.
or c sends some type of cookie back.
And I am still confused as to how to actually redirect from my api to a mobile application.
2
Answers
In the end I ended up with the following login flow
User is directed to Oauth provider Oauth provider returns an access token to the client the client sends the access token to my api my api sends a renew request to the Oauth provider the Oauth provider validates the token and returns a new one to my api my api exchanges the access token for a jwt token my api returns the jwt token to the client
In my opinion it is the only correct way to authenticate SPA applications, and it is important to renew the Oauth token the client provides rather than blindly exchanging for a jwt as you can't trust the client, and is better than issuing redirects from the api that isn't very restfull
Instead of dealing with 2 services, your spa should talk to a single auth service in your backend. You register your service as the oauth callback and you handle oauth/jwt as you described. Your auth service can also be the decision point for user (re-)authentication. Since your frontend calls your backend directly, you can now return the json payload back to your web/mobile caller.