0

请使用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);
    }
}
4

0 回答 0