×ðÁú¿­Ê±¹ÙÍøµÇ¼

Laravel¿ª·¢£ºÔõÑùʹÓÃLaravel SanctumΪSPAÌṩAPIÉí·ÝÑéÖ¤£¿

laravel¿ª·¢£ºÔõÑùʹÓÃlaravel sanctumΪspaÌṩapiÉí·ÝÑéÖ¤£¿

Ëæ×ŵ¥Ò³Ó¦ÓóÌÐò£¨SPA£©µÄÊ¢ÐУ¬ÎÒÃÇÐèÒªÒ»ÖÖ¿É¿¿µÄÒªÁìÀ´±£»¤ÎÒÃǵÄAPIÃâÊÜδ¾­ÊÚȨµÄ»á¼ûºÍ¹¥»÷  ¡£Laravel SanctumÊÇLaravelÌṩµÄÒ»¸öÇáÁ¿¼¶µÄÈÏ֤ϵͳ£¬ËüΪSPAÌṩÇáËɵÄÉí·ÝÑéÖ¤  ¡£±¾ÎĽ«ÏòÄúչʾÔõÑùʹÓÃLaravel SanctumΪSPAÌṩAPIÉí·ÝÑéÖ¤  ¡£

ʹÓÃLaravel Sanctum

Laravel SanctumÊÇLaravel 7.x°æ±¾ÖеÄÒ»¸ö¹Ù·½°ü£¬ÓÃÓÚAPIÉí·ÝÑéÖ¤  ¡£Laravel SanctumʹÓøÃAPIµÄTokenÀ´Ê¶±ðÓû§Éí·Ý£¬²¢ÇÒ¿ÉÒÔͨ¹ýʹÓÃtokenÇáËÉÖ´Ðжà¸öÉí·ÝÑéÖ¤µÄ¹¹½¨  ¡£

×°ÖÃLaravel Sanctum

Ê×ÏÈ£¬ÐèÈ·±£ÒÑ×°ÖÃLaravel¿ò¼Ü  ¡£

ҪװÖÃlaravel sanctum£¬¿ÉÒÔʹÓÃÒÔÏÂÏÂÁî

composer require laravel/sanctum

µÇ¼ºó¸´ÖÆ

½«ServiceProviderÌí¼Óµ½config/app.phpÎļþµÄprovidersÁбíÖÐ  ¡£

'providers' => [
    // ...
    LaravelSanctumSanctumServiceProvider::class,

],

µÇ¼ºó¸´ÖÆ

ÏÖÔÚ£¬¿ÉÒÔÔËÐÐÒÔÏÂÏÂÁîÐû²¼ÐëÒªµÄÊý¾Ý¿âǨáãºÍSanctumÉèÖà  ¡£

php artisan vendor:publish --provider="LaravelSanctumSanctumServiceProvider"

µÇ¼ºó¸´ÖÆ

Ö´ÐÐÒÔÏÂÏÂÁîÒÔÔËÐÐǨá㣺

php artisan migrate

µÇ¼ºó¸´ÖÆ

ʹÓÃSanctum¾ÙÐÐĬÈÏÉí·ÝÑéÖ¤

Sanctum°üÀ¨APIºÍµ¥Ò³Ó¦ÓóÌÐòÉí·ÝÑéÖ¤µÄĬÈÏʵÏÖ  ¡£¿ÉÒÔͨ¹ýΪÓû§Ä£×ÓʹÓÃSanctumTraitsHasApiTokens traitÀ´ÆôÓÃĬÈÏÉí·ÝÑéÖ¤  ¡£

½«HasApiTokens traitÌí¼Óµ½Óû§Ä£×Ó

<?php

namespace AppModels;

use IlluminateFoundationAuthUser as Authenticatable;
use IlluminateNotificationsNotifiable;
use LaravelSanctumHasApiTokens;

class User extends Authenticatable
{
    use Notifiable, HasApiTokens;

    // ...
}

µÇ¼ºó¸´ÖÆ

ΪÁ˸üºÃµÄÚ¹ÊÍ£¬ÎÒÃǽ«Ê¹ÓÃÒ»¸ö¼òÆÓµÄSPAʾÀý  ¡£¼ÙÉèʾÀýµÄURLΪhttp://spa.testºÍͨ¹ýhttp://api.spa.test¹ûÕæµÄAPI  ¡£

ÔÚLaravelÖÐÉèÖÃCORS

½«ÏÂÃæµÄ´úÂëÌí¼Óµ½app/Providers/AppServiceProvider.phpÎļþÖÐÀ´ÔÊÐí¿çÓò×ÊÔ´¹²Ïí£¨CORS£©  ¡£

...
use IlluminateSupportFacadesSchema;
use IlluminateSupportFacadesURL;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Schema::defaultStringLength(191);

        if (config('app.env') === 'production') {
            URL::forceScheme('https');
        }

        $headers = [
            'Access-Control-Allow-Origin' => '*',
            'Access-Control-Allow-Methods' => 'POST, GET, OPTIONS, PUT, DELETE',
            'Access-Control-Allow-Headers' => 'Origin, Content-Type, Accept, Authorization, X-Request-With',
            'Access-Control-Allow-Credentials' => 'true',
        ];
        $this->app['router']->middleware('api')->get('/sanctum/csrf-cookie', function () {
            return response()->json(['status' => 'success']);
        });

        foreach ($headers as $key => $value) {
            config(['cors.supportsCredentials' => true]);
            config(['cors.paths.api/*' => [
                'allowedOrigins' => ['http://spa.test'],
                'allowedHeaders' => [$key],
                'allowedMethods' => ['*'],
                'exposedHeaders' => [],
                'maxAge' => 86400,
            ]]);
        }
    }
}

µÇ¼ºó¸´ÖÆ

½«ÉÏÊö´úÂëÖеÄhttp://spa.testÌ滻ΪÄúµÄSPAµÄURL  ¡£

ÁîÅÆÑéÖ¤ºÍAPI±£»¤ËµÃ÷

ÔÚ¿ØÖÆÆ÷ÖУ¬ÎÒÃÇ¿ÉÒÔʹÓÃSanctumµÄauthÖÐÑë¼þÀ´±£»¤Â·ÓÉ

public function index(Request $request)
{
    $user = $request->user();
    // ...
}

public function store(Request $request)
{
    $user = $request->user();
    // ...
}

public function destroy(Request $request, string $id)
{
    $user = $request->user();  
    // ...
}

public function update(Request $request, string $id)
{
    $user = $request->user();
    // ...
}

µÇ¼ºó¸´ÖÆ

Õâ»á´ÓÇëÇó±êÍ·ÖлñÈ¡SanctumÊÚȨÁîÅÆ£¬²¢Ê¹ÓøÃÁîÅÆÑéÖ¤Óû§  ¡£ÈôÊÇδÔÚ±êÍ·ÖÐÌṩÊÚȨÁîÅÆ£¬Ôò½«·µ»Ø401δ¾­ÊÚȨµÄ¹ýʧ  ¡£

·¢³öÊÚȨÁîÅÆÇëÇó

ÔÚÎÒÃǵÄSPAÖУ¬ÎÒÃÇ¿ÉÒÔʹÓÃaxios¿âÀ´Ê¹ÓÃAPI²¢»ñÈ¡ÁîÅÆ  ¡£Òª»ñÈ¡ÊÚȨÁîÅÆ£¬ÎÒÃÇÐèÒªÊ×ÏÈ»ñÈ¡CSRFÁîÅÆ£¬ÒÔÊÇÎÒÃÇÐèÒª·¢ËÍÒ»¸öGETÇëÇóÀ´»ñÈ¡Ëü  ¡£

axios.get('http://api.spa.test/sanctum/csrf-cookie').then(response => {
    axios.post('http://api.spa.test/login', {
        username: this.username,
        password: this.password
    }).then(response => {
        axios.defaults.headers.common['Authorization'] = `Bearer ${response.data.token}`;
        this.$router.push({ name: 'home' });
    });
});

µÇ¼ºó¸´ÖÆ

ÉÏÃæµÄ´úÂ뽫ÔÚhttp://api.spa.testÖз¢³öPOSTÇëÇó£¬ÔÚЧÀÍÆ÷ÉϽ¨ÉèÒ»¸öеÄSanctumÊÚȨÁîÅÆ£¬²¢½«ÁîÅÆ×÷Ϊresponse.data.token¾ÙÐÐÏìÓ¦  ¡£ÒÔºó£¬ÎÒÃÇ¿ÉÒÔ½«ÁîÅÆÌí¼Óµ½axiosµÄͨÓÃÍ·ÎļþÖУ¬ÒÔÔÚSPAÖÐʹÓÃËùÓкóÐøÇëÇó  ¡£

×¢ÖØ£¬´ËʾÀý¼ÙÉèÓÐÒ»¸öÃûΪ¡°login¡±µÄ·ÓÉ  ¡£

Sanctum»¹ÎªÎÒÃÇÌṩÁËÒ»¸ölogout·ÓÉÀ´×÷·ÏÊÚȨÁîÅÆ  ¡£

axios.post('http://api.spa.test/logout').then(response => {
    delete axios.defaults.headers.common['Authorization'];
    this.$router.push({ name: 'login' });
});

µÇ¼ºó¸´ÖÆ

½áÂÛ

Laravel SanctumÊÇÒ»¸öÇáÁ¿¼¶µÄ¼òÖÊÆÓÓõÄÉí·ÝÑé֤ϵͳ£¬ËüÒ×ÓÚ¼¯³ÉºÍʹÓ㬲¢ÌṩĬÈϵÄÉí·ÝÑéÖ¤¹¦Ð§£¬ÊÇSPAÉí·ÝÑéÖ¤µÄ¾ø¼Ñ½â¾ö¼Æ»®  ¡£Ò»µ©ÄúÓëSanctumÒ»ÆðʹÓã¬Äú½«²»ÔÙÐèÒª±àд×Ô¼ºµÄÉí·ÝÑé֤ϵͳ  ¡£ËüÄܹ»ÈÃÎÒÃÇΪÎÒÃǵÄAPI¿ìËÙʵÏÖÇå¾²µÄÉí·ÝÑéÖ¤£¬²¢ÈÃÎÒÃǵÄSPAÓëAPIÔں̵ܶÄʱ¼äÄÚ½»»¥  ¡£

ÒÔÉϾÍÊÇLaravel¿ª·¢£ºÔõÑùʹÓÃLaravel SanctumΪSPAÌṩAPIÉí·ÝÑéÖ¤£¿µÄÏêϸÄÚÈÝ£¬¸ü¶àÇë¹Ø×¢±¾ÍøÄÚÆäËüÏà¹ØÎÄÕ£¡

ÃâÔð˵Ã÷£ºÒÔÉÏչʾÄÚÈÝȪԴÓÚÏàÖúýÌå¡¢ÆóÒµ»ú¹¹¡¢ÍøÓÑÌṩ»òÍøÂçÍøÂçÕûÀí£¬°æȨÕùÒéÓë±¾Õ¾Î޹أ¬ÎÄÕÂÉæ¼°¿´·¨Óë¿´·¨²»´ú±í×ðÁú¿­Ê±¹ÙÍøµÇ¼ÂËÓÍ»úÍø¹Ù·½Ì¬¶È£¬Çë¶ÁÕß½ö×ö²Î¿¼  ¡£±¾ÎĽӴýתÔØ£¬×ªÔØÇë˵Ã÷À´ÓÉ  ¡£ÈôÄúÒÔΪ±¾ÎÄÇÖÕ¼ÁËÄúµÄ°æȨÐÅÏ¢£¬»òÄú·¢Ã÷¸ÃÄÚÈÝÓÐÈκÎÉæ¼°ÓÐÎ¥¹«µÂ¡¢Ã°·¸Ö´·¨µÈÎ¥·¨ÐÅÏ¢£¬ÇëÄúÁ¬Ã¦ÁªÏµ×ðÁú¿­Ê±¹ÙÍøµÇ¼ʵʱÐÞÕý»òɾ³ý  ¡£

Ïà¹ØÐÂÎÅ

ÁªÏµ×ðÁú¿­Ê±¹ÙÍøµÇ¼

18523999891

¿É΢ÐÅÔÚÏß×Éѯ

ÊÂÇéʱ¼ä£ºÖÜÒ»ÖÁÖÜÎ壬9:30-18:30£¬½ÚãåÈÕÐÝÏ¢

QR code
ÍøÕ¾µØͼ