I have a fully done project made with a Laravel back end and a react front end. The react app is wrapped in the Laravel code, and will be available only after a login and some selections, which are all done in laravel with its views. I want to make the react app as a standalone app, and make the laravel code into an api, served from a server via. an url, such that the react app will work by making requests to the laravel api.
So my first problem is the following: Is there a way to implement API to my laravel code which mimics my allready existing login implementation?
Since my question is pretty broad, I was not sure what code to provide with this question. The code follows the MVC design pattern, so feel free to ask for some parts of the code.
As a slight off-topic question (don't read this if you just want to help with the laravel stuff): The reason I want to decouple the laravel back end and the react front end app, is to wrap the react app in electron to make it an offline app, using the laravel backend. Is this a reasonable approach?
Edit: I found the crux of the problem is how to perform a login "API style" versus the login form laravel provides. So I think I need to implement a login with laravel Passport, retrieving a user with credentials matching the user one would get by logging in through the laravel login form. But the logic in the laravel login form is hard for me to see through, so I could use a helping hand on how to do this.
Below is the code of my login controller, and the associated middleware. Again, tell if you need any more code.
Login controller (from App/http/controllers/auth):
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
/*
|---------------------------------------------------------------------
| Login Controller
|------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo = '/';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}
Middleware (from App/http/Kernel.php):
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware \AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
Edit-2:
Here is the code for my web.php routes:
<?php
/*
|---------------------------------------------------------------
| Web Routes
|----------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Auth::routes();
Route::get('/', 'HomeController@index')->name('home');
Route::get('/home', 'HomeController@index')->name('home');
Route::get('/setlocale/{locale}', function (Request $request, $locale) {
if (in_array($locale, \Config::get('app.locales'))) {
session()->put('locale', $locale);
}
return redirect()->back();
});
Route::get('/profile', 'UserController@show')->name('profile');
Route::patch('/profile', 'UserController@update')->name('users.update');
Route::get('/scan', 'HomeController@index')->name('scan.index');
Route::get('/scan/new', 'ScanController@new')->name('scan.new');
Route::get('/scan/{id}', 'ScanController@show')->name('scan.show');
Route::post('/scan', 'ScanController@create')->name('scan.create');
Route::patch('/scan/{id}', 'ScanController@update')->name('scan.update');
Route::delete('/scan/{id}', 'ScanController@destroy')->name('scan.destroy');
// save SCAN JSON
Route::post('/scan/{id}/save', 'ScanController@save')->name('scan.save');
Edit 3:
First thing, when I create the access token, what is stored in /oauth/personal-access-tokens looks like this:
0:
client:
created_at: "2019-01-04 13:00:48"
id: 3
name: "SCAN Personal Access Client"
password_client: false
personal_access_client: true
redirect: "http://localhost"
revoked: false
updated_at: "2019-01-04 13:00:48"
user_id: null
__proto__: Object
client_id: 3
created_at: "2019-01-15 13:52:22"
expires_at: "2020-01-15 13:52:22"
id: "0321b2d622bd7267273225a64cf6f1723cc74b86076831432fb5af4885051c6776bb8ea77c0d7407"
name: "MyApp"
revoked: false
scopes: []
updated_at: "2019-01-15 13:52:22"
user_id: 1
__proto__: Object
See in the first client, made at 13:00:48, the uder_id is null. Is that a problem?
Secondly, here is how I try making a request using axios, using the function login to get an access token (and I do get the access token), and my API is running on localhost:4321
login = async () => {
return axios.post('http://localhost:4321/api/login', {
grant_type: 'password',
client_id: 5,
client_secret: 'd3zuZL6KbBI4DOq4Z7NQkP1ezrAj5GMjgo39',
email: 'my mail, used to login',
password: 'my password',
scope: '',
})
}
async componentDidMount() {
const accessTokenData = await this.login();
var config = {
headers: {
Authorization: "bearer " + accessToken
},
grant_type: 'password',
client_id: 'PassGrantClient',
client_secret: 'd3zuZL6KbBI4zsDOq4Z7NQkP1ezrAj5GMjgo39',
scope: '',
};
axios.post(
'http://localhost:4321/api/getInterview',
{},
config
).then((response) => {
console.log(response)
})
}
Where the getInterview route points to the function
public function getInterview()
{
$user = Auth::user();
return response()->json($user);
}
which returns 401.As you can see, I'm not sure what to put where :). If you need more code, feel free to ask :).