Skip to content
Advertisement

Laravel Auth:api will not persisting

I’m realizing platform web and app that work with Laravel 6 in back-end. I set auth web for platform web and auth api (with Laravel JWT) for the app. When I signin with app, Auth doesn’t persist and with subsequent calls I can’t to refresh the token nor to get user info. The code is below:

routes/api.php

<? php
use IlluminateHttpRequest;

Route::group([
    'middleware' => 'api',
    'prefix' => 'auth'

], function ($router) {

    Route::post('login', 'AuthController@login');
    Route::post('logout', 'AuthController@logout');
    Route::post('refresh', 'AuthController@refresh');
    Route::post('me', 'AuthController@me');
    Route::get('test', 'AuthController@test');

});

AuthController.php

<?php

namespace AppHttpControllers;

use IlluminateSupportFacadesAuth;
use AppHttpControllersController;
use IlluminateFoundationAuthAuthenticatesUsers;
use JWTAuth;

class AuthController extends Controller
{
    /**
     * Create a new AuthController instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth:api', ['except' => ['login']]);
    }

    /**
     * Get a JWT via given credentials.
     *
     * @return IlluminateHttpJsonResponse
     */
    public function login()
    {
        $credentials = request(['email', 'password']);
        
        if (! $token = auth('api')->attempt($credentials)) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }
        
        return $this->respondWithToken($token);
    }

    /**
     * Get the authenticated User.
     *
     * @return IlluminateHttpJsonResponse
     */
    public function me()
    {
        return response()->json(auth('api')->user());
    }

    /**
     * Log the user out (Invalidate the token).
     *
     * @return IlluminateHttpJsonResponse
     */
    public function logout()
    {
        auth('api')->logout();

        return response()->json(['message' => 'Successfully logged out']);
    }

    /**
     * Refresh a token.
     *
     * @return IlluminateHttpJsonResponse
     */
    public function refresh()
    {
        return $this->respondWithToken(aut('api')->refresh());
    }

    /**
     * Get the token array structure.
     *
     * @param  string $token
     *
     * @return IlluminateHttpJsonResponse
     */
    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => Auth::guard('api')->factory()->getTTL() * 60,
            'user' => Auth::guard('api')->user()
        ]);
    }
}

Kernel middlewares

protected $middleware = [
        AppHttpMiddlewareTrustProxies::class,
        AppHttpMiddlewareCheckForMaintenanceMode::class,
        IlluminateFoundationHttpMiddlewareValidatePostSize::class,
        AppHttpMiddlewareTrimStrings::class,
        IlluminateFoundationHttpMiddlewareConvertEmptyStringsToNull::class,
        FruitcakeCorsHandleCors::class,
        IlluminateSessionMiddlewareStartSession::class,
        IlluminateSessionMiddlewareAuthenticateSession::class,
    ];

    
    protected $middlewareGroups = [
        'web' => [
            AppHttpMiddlewareEncryptCookies::class,
            IlluminateCookieMiddlewareAddQueuedCookiesToResponse::class,
            IlluminateSessionMiddlewareStartSession::class,
            IlluminateSessionMiddlewareAuthenticateSession::class,
            IlluminateViewMiddlewareShareErrorsFromSession::class,
            AppHttpMiddlewareVerifyCsrfToken::class,
            IlluminateRoutingMiddlewareSubstituteBindings::class,
        ],

        'api' => [
            'throttle:60,1',
            IlluminateRoutingMiddlewareSubstituteBindings::class,
            IlluminateSessionMiddlewareStartSession::class,
            IlluminateSessionMiddlewareAuthenticateSession::class,
        ],
    ];

    /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'auth' => AppHttpMiddlewareAuthenticate::class,
        'auth.basic' => IlluminateAuthMiddlewareAuthenticateWithBasicAuth::class,
        'bindings' => IlluminateRoutingMiddlewareSubstituteBindings::class,
        'cache.headers' => IlluminateHttpMiddlewareSetCacheHeaders::class,
        'can' => IlluminateAuthMiddlewareAuthorize::class,
        'guest' => AppHttpMiddlewareRedirectIfAuthenticated::class,
        'password.confirm' => IlluminateAuthMiddlewareRequirePassword::class,
        'signed' => IlluminateRoutingMiddlewareValidateSignature::class,
        'throttle' => IlluminateRoutingMiddlewareThrottleRequests::class,
        'verified' => IlluminateAuthMiddlewareEnsureEmailIsVerified::class,
    ];

    /**
     * The priority-sorted list of middleware.
     *
     * This forces non-global middleware to always be in the given order.
     *
     * @var array
     */
    protected $middlewarePriority = [
        IlluminateSessionMiddlewareStartSession::class,
        IlluminateViewMiddlewareShareErrorsFromSession::class,
        AppHttpMiddlewareAuthenticate::class,
        IlluminateRoutingMiddlewareThrottleRequests::class,
        IlluminateSessionMiddlewareAuthenticateSession::class,
        IlluminateRoutingMiddlewareSubstituteBindings::class,
        IlluminateAuthMiddlewareAuthorize::class,
    ];

config auth.php

'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'jwt',
            'provider' => 'users',
            'hash' => false,
        ],
    ],

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => AppModelsUser::class,
        ],

    ],

User model implements JWTSubject. I tryied with Auth:guard(‘api’) and JWTAuth, too. Login works, refresh token doesn’t works and the route “me” returns empty object. Can You help me?

Advertisement

Answer

You should pass token with your post request for me function, security wise it is advisable.

Edit your me function

From :

public function me()
    {
        return response()->json(auth('api')->user());
    }

To:

public function me(Request $request)
    {
        $this->validate($request, [
            'token' => 'required'
        ]);

        $user = JWTAuth::authenticate($request->token);

        return response()->json(['user' => $user]);
    }

Refresh function should be

From:

public function refresh()
    {
        return $this->respondWithToken(auth('api')->refresh());
    }

To:

public function refresh()
    {
        return $this->respondWithToken(auth()->refresh());
    }

Read More about JWT

Hope this will be useful.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement