Laravel 8: Using Fortify in APIs
Asked Answered
P

3

19

Can Laravel Fortify be used in the context of API? From what I understand, Fortify (although being headless, i.e. doesn't include a UI layer) allows us to customize Login and Register pages, but it automatically redirects to HOME page upon successful authentication. And although the HOME page is customizable, that is not how API logins normally work. It should simply return a success token in JSON format without redirects of any kind.

There is an authenticateUsing function in Fortify, but even that simply allows us to customize authentication logic and not the returned data. Redirection is still performed by Fortify.

How can I use Fortify in the context of REST API?

Note: I'm going to use it from my Vue front-end application. I'm also going to get Sanctum into the game, but before that I just wanted to see if I can do regular token-based authentication using Fortify without having to write my own login, register and logout routes and controller functions.

Privative answered 24/9, 2020 at 4:58 Comment(2)
Did you manage to solve it? Do you have an example? I'd like to not use registerView(), is that possible?Rabbin
Yes I did. See accepted answer and its comments. If you're using a front-end framework such as Vue, just use Sanctum to have a session-based authentication system for you. On the client-side, develop your own register/login UI and use axios to handle session cookies for you. Then you can your API functions, get back JSON-encoded response and handle it on the client-sdie.Privative
T
16

Just set 'Accept' header with 'application/json' or 'application/javascript' then fortify will response json formatted body not redirection.

by the way, use Sanctum instead of Passport for SPA is easier to keep token securely. google about where to store API token for SPA then you will find out why.

Tobitobiah answered 13/10, 2020 at 2:13 Comment(1)
Could you please provide a simple example on how to e.g. use the /register endpoint? I am currently lost on how to use it with a simple curl or postman. It seems you always must call registerView() first, which I don't want to use.Rabbin
R
16

Authentication can either be Session-based or Token-based.

Laravel Fortify only provides the backend logic nessecery for session-based authentication and therefore is not intended for token-based API authentication.

If you need token-based API authentication, you can use either Sanctum or Passport depending on your needs. But You'll have to write a bit of code, in either case.

If you decide to go with Laravel Passport, I have a boilerplate project that might be of use: https://github.com/pktharindu/laravel-api-boilerplate-passport

Rejoinder answered 24/9, 2020 at 8:9 Comment(4)
Yep. That's exactly what's confusing. When using Fortify, we are provided with basic authentication routes and services (register, login, reset-password etc.) out-of-the-box, but as u say it is only for session-based authentication. On the other hand, Sanctum can do both session and token based authentication, but doesn't provide any authentication routes. Is my understanding correct?Privative
I was already using Passport in my project till Laravel 7 and had created all those authentication routes for my API. With Laravel 8, they are advising to move to Sanctum unless we have a need for full OAuth implementation, so I read the docs and got the impression that Sanctum will do token management for me and Fortify (being headless) will provide me the authentication routes and services out-of-the-box, so with these two packages in place, I'll get rid of both my custom login/logout functions as well as Passport. Looks like that understanding is not correct.Privative
Fortify is pretty much useless if you have a separate frontend app. You can use either Sanctum or Passport. But you'll have to set up the routing yourself. Using Sanctum makes sense if it fits your need and you are starting from scratch. But if you already have Passport installed I'd just keep it as is as moving to Sanctum doesn't provide you with any benefit over Passport.Rejoinder
Thanks. That makes sense.Privative
T
16

Just set 'Accept' header with 'application/json' or 'application/javascript' then fortify will response json formatted body not redirection.

by the way, use Sanctum instead of Passport for SPA is easier to keep token securely. google about where to store API token for SPA then you will find out why.

Tobitobiah answered 13/10, 2020 at 2:13 Comment(1)
Could you please provide a simple example on how to e.g. use the /register endpoint? I am currently lost on how to use it with a simple curl or postman. It seems you always must call registerView() first, which I don't want to use.Rabbin
I
2

The redirects reason in my case was the default laravel RedirectIfAuthenticated provider.

By default in laravel 8 that provider looks like

<?php

namespace App\Http\Middleware;

use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Support\Facades\Auth;

class RedirectIfAuthenticated
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string[]|null  ...$guards
     * @return mixed
     */
    public function handle($request, Closure $next, ...$guards)
    {
        $guards = empty($guards) ? [null] : $guards;

        foreach ($guards as $guard) {
            if (Auth::guard($guard)->check()) {
                return redirect(RouteServiceProvider::HOME);
            }
        }

        return $next($request);
    }
}

just replace default foreach by the following code with that:

foreach ($guards as $guard) {
    if (Auth::guard($guard)->check()) {
        if ($request->expectsJson()) {
            return response()->json([
               'error' => 'Already authenticated.'
            ], 406);
        }
        return redirect(RouteServiceProvider::HOME);
    }
}

Don't forget that for $request->expectsJson() to work fine you should include Accept: application/json in the request headers.

Inform answered 2/10, 2022 at 20:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.