Support the ongoing development of Laravel.io →
posted 7 years ago

I'd like for this code to be reviewed - mostly in terms of any potential security flaws, but would like to also hear anything else.

I've have been looking at ways using Social Authentication to authenticate a 1st party Single Page Application with my API.

I also have a concern. Detailed after the code.

Here is my final solution:

I needn't post the code for the SPA as it's trivial. However here is the sudo flow:

SPA follows oAuth flow to retrieve an access_token from a identity provider

SPA posts retrieved access_token to API

API verifies access token against identity provider then creates/retrieves a user

API logs in user and returns an access token to the SPA

Here is the code which handles the last 2 points:

<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Http\Request;
use Laravel\Socialite\Facades\Socialite;

class SocialAuthController extends Controller
{
    private $provider;
    private $access_token;
    private $token;

    public function __construct(Request $request)
    {
        $this->middleware('auth:api', ['except' => ['token']]);

        /**
         * Set any expected parameters
         */
        $this->provider = ($request->has('provider') ? $request->get('provider') : false);
        $this->access_token = ($request->has('access_token') ? $request->get('access_token') : false);
    }

    /**
     * Exchanges an access_token from identity providers for an access_token to be used to authenticate the api.jwt auth guard
     * @return \Illuminate\Http\JsonResponse
     */
    public function token()
    {
        // authenticate the token against the provider
        $user = Socialite::driver($this->provider)->stateless()->userFromToken($this->access_token);

        // find or create an authenticated user
        if (!$authenticatedUser = User::where('provider_id', $user->id)->first()) {
            $authenticatedUser = User::create([
                'email' => $user->email,
                'name' => $user->name,
                'provider' => $this->provider,
                'provider_id' => $user->id
            ]);
        }

        // login the user & get an access token for the API
        $this->token = auth()->guard('api')->login($authenticatedUser);

        // respond with the access token
        return $this->respondWithToken($this->token);
    }

    public function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => 'todo'
        ]);
    }
}

My concern is - what's to stop anyone sending an access_token from their own app, then consuming my data from it?

At the moment my CORS setup allows all origins. Will only allowing the origin from my SPA be sufficient security to prevent this?

Many thanks!

Last updated 3 years ago.

juanicastellan0 liked this thread

1

Sign in to participate in this thread!

Eventy

Your banner here too?

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2025 Laravel.io - All rights reserved.