请使用laravel sanctum 和 fortify为我的 react 应用程序创建一个登录 API ,它可以正常工作并验证用户,但是,每当我刷新 react spa 时,它会自动注销用户并将他路由回主页,我希望用户除非自己手动注销,否则保持登录状态。请问我该怎么做?
这是我使用材料 ui 的登录页面
import React,{ useState} from 'react'
import FormInput from './CustomTextField'
import { Typography,Button } from '@material-ui/core';
import { useForm, FormProvider } from 'react-hook-form';
import useStyles from './Styles';
import Dashboard from "./Dashboard";
import { Link, } from 'react-router-dom';
import Checkbox from '@material-ui/core/Checkbox';
const Login = ({loggedIn, saveData,logout, emailErrors }) => {
const classes= useStyles();
const methods=useForm();
const [checked, setChecked] = useState(false);
const checkBox=()=>{
if (checked===false){
setChecked(true)
}
else{
setChecked(false)
}
}
console.log('checked: ' + checked)
console.log(loggedIn)
return !loggedIn ? (// if is not logged in show this component
<>
<Typography variant="h6" justify gutterBottom> Login
</Typography>
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit((data) => saveData( data) )}>
<div style={{ justifyContent: 'center',
alignContent: 'center' }}>
<FormInput required name='email' label='Email'/>
{/* this shows errors from the laravel backend if login data is not in a data base */}
{emailErrors!=='' ? <div style={{color:'red'}}>{emailErrors} <br />
</div> : null}
<FormInput required name='password' label='Password'/>
</div>
<div style={{ display: 'flex', }}>
<Checkbox onClick={checkBox} /><h4> Remember Me</h4>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<Button type="submit"
variant="contained" className={classes.blue} color="primary">Log In
</Button>
</div>
</form>
</FormProvider>
<p>Don't Have an account? <Link to='/register' style={{fontWeight:'bolder'}}>Sign Up</Link></p>
</>
) : <Dashboard logout={logout}/> // if you are logged In shows this
}
export default Login
这是我的 kernal.php 中间件组
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
这是在后端处理登录的 laravel fortify authenticateSessionController.php。
<?php
namespace Laravel\Fortify\Http\Controllers;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Routing\Pipeline;
use Laravel\Fortify\Actions\AttemptToAuthenticate;
use Laravel\Fortify\Actions\EnsureLoginIsNotThrottled;
use Laravel\Fortify\Actions\PrepareAuthenticatedSession;
use Laravel\Fortify\Actions\RedirectIfTwoFactorAuthenticatable;
use Laravel\Fortify\Contracts\LoginResponse;
use Laravel\Fortify\Contracts\LoginViewResponse;
use Laravel\Fortify\Contracts\LogoutResponse;
use Laravel\Fortify\Features;
use Laravel\Fortify\Fortify;
use Laravel\Fortify\Http\Requests\LoginRequest;
use Illuminate\Support\Facades\Auth;
class AuthenticatedSessionController extends Controller
{
/**
* The guard implementation.
*
* @var \Illuminate\Contracts\Auth\StatefulGuard
*/
protected $guard;
/**
* Create a new controller instance.
*
* @param \Illuminate\Contracts\Auth\StatefulGuard $guard
* @return void
*/
public function __construct(StatefulGuard $guard)
{
$this->guard = $guard;
}
/**
* Show the login view.
*
* @param \Illuminate\Http\Request $request
* @return \Laravel\Fortify\Contracts\LoginViewResponse
*/
public function create(Request $request): LoginViewResponse
{
return app(LoginViewResponse::class);
}
/**
* Attempt to authenticate a new session.
*
* @param \Laravel\Fortify\Http\Requests\LoginRequest $request
* @return mixed
*/
public function store(LoginRequest $request)
{
$password = $request->password ;
Auth::logoutOtherDevices($password);
return $this->loginPipeline($request)->then(function ($request) {
return app(LoginResponse::class);
});
}
/**
* Get the authentication pipeline instance.
*
* @param \Laravel\Fortify\Http\Requests\LoginRequest $request
* @return \Illuminate\Pipeline\Pipeline
*/
protected function loginPipeline(LoginRequest $request)
{
if (Fortify::$authenticateThroughCallback) {
return (new Pipeline(app()))->send($request)->through(array_filter(
call_user_func(Fortify::$authenticateThroughCallback, $request)
));
}
if (is_array(config('fortify.pipelines.login'))) {
return (new Pipeline(app()))->send($request)->through(array_filter(
config('fortify.pipelines.login')
));
}
return (new Pipeline(app()))->send($request)->through(array_filter([
config('fortify.limiters.login') ? null : EnsureLoginIsNotThrottled::class,
Features::enabled(Features::twoFactorAuthentication()) ? RedirectIfTwoFactorAuthenticatable::class : null,
AttemptToAuthenticate::class,
PrepareAuthenticatedSession::class,
]));
}
/**
* Destroy an authenticated session.
*
* @param \Illuminate\Http\Request $request
* @return \Laravel\Fortify\Contracts\LogoutResponse
*/
public function destroy(Request $request): LogoutResponse
{
$this->guard->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return app(LogoutResponse::class);
}
}