Ben
Ben

Reputation: 62444

Token-based Authentication Laravel 5.5

Out of the gate, the auth config for Laravel specifies a token-based authentication approach for users:

'guards' => [
    'web' => [
        'driver'   => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver'   => 'token',
        'provider' => 'users',
    ],
],

I have a few ajax endpoints I want to secure so no one outside of my application can interact with them. I've looked at Passport but it seems I may not actually need it given this auth configuration. How can I utilize this token to secure my ajax endpoints and if possible, identify the user the request belongs to?

Currently my api.php route file looks like:

//Route::middleware('auth:api')->group(function () {
    Route::post('subscribe', 'SubscriptionController@create');
    Route::post('unsubscribe', 'SubscriptionController@delete');
//});

I thought Laravel might've handled auth or something out of the gate for VueJS implementation but it doesn't look like it. My ajax request looks like:

this.$http.post('/api/subscribe', {
    subscribed_by: currentUser,
    game_id: this.gameId,
    guild_discord_id: this.guildDiscordId,
    channel_id: newChannelId,
    interests: this.interests.split(',')
}).then(response => {
    // success
}, response => {
    console.error('Failed to subscribe');
});

Upvotes: 1

Views: 671

Answers (2)

Ben
Ben

Reputation: 62444

The solution I took was to not put ajax endpoints in the api namespace. By putting them as web routes instead of api it'll use CSRF (cross-site request forgery) protection to validate the route. So only if it comes from my domain will it be authenticated. This is ONLY useful when the site is served in https.

Upvotes: 0

thomas_inckx
thomas_inckx

Reputation: 470

As Maraboc already said, you should start by creating a column api_token: $table->string('api_token', 60)->unique(); in your users table.

Make sure each newly created user gets a token assigned, and encrypt it: $user->api_token = encrypt(str_random(60));

Next, you could define a Javascript variable in the footer of your app:

window.Laravel = <?php echo json_encode([
    'apiToken' => !empty(Auth::user()) ? decrypt(Auth::user()->api_token) : ''
]); ?>;

Later, when you want to make a request to an endpoint, you should add a header, authorizing the user:

let url = '/path/to/your-endpoint.json';
let data = {
    headers: {
        'Authorization': 'Bearer ' + Laravel.apiToken
    }
};

axios.get(url, data)
    .then(response => console.dir(response));

Finally, in your controller, you can get your User instance by using Laravel's guard:

$user = !empty(Auth::guard('api')->user()) ? Auth::guard('api')->user() : null;

Hope this helps! BTW: these articles helped me on my way:

Upvotes: 0

Related Questions