Auth :: user () имеет значение null после успешной аутентификации Passport - PullRequest
0 голосов
/ 11 января 2020

Я использую пароль для аутентификации пользователя, и после каждой аутентификации я назначаю защищенного повара ie, который хранит токен паспорта. Я могу успешно пройти аутентификацию с использованием метода Auth::attempt(), но Auth::user() имеет значение null. Даже в том же контроллере для метода logout () пользователь не определен, и я не могу даже Auth::logout().

Метод входа:

public function login(Request $request)
{
    $request->validate([
        'email' => 'required|string|email',
        'password' => 'required|string',
    ]);
    $credentials = \request(['email', 'password']);
    if (Auth::attempt($credentials)) {
        $user = Auth::user();
        $token = $user->createToken('Personal Access Token')->accessToken;
        $cookie = $this->getSessionCookie($token);
        return response()
            ->json([
                'user' => $user,
                'token' => $token,
            ], 200)
            ->cookie(
                $cookie['name'],
                $cookie['value'],
                $cookie['minutes'],
                $cookie['path'],
                $cookie['domain'],
                $cookie['secure'],
                $cookie['httponly'],
                $cookie['samesite']
            );
    } else {
        return response()->json([
            'error' => 'Invalid Credentials',
        ], 422);
    }
}

Метод выхода из системы:

public function logout(Request $request)
{
    $request->user()->token()->each(function ($token, $key) {
        $token->delete();
    });
    $cookie = \Cookie::forget('auth_token');
    Auth::logout();
    return response()->json([
        'message' => 'Logged out successfully.'
    ], 200)->withCookie($cookie);
}

Здесь Auth::logout() производит Method Illuminate\Auth\RequestGuard::logout does not exist. В противном случае выход из системы будет успешным.

Мои маршруты API:

Route::group(['prefix' => 'v1'], function() {

    // Authentication
    Route::post('/login', 'AuthController@login');
    Route::post('/register', 'AuthController@register');
    Route::post('/password/reset', 'AuthController@sendPasswordResetLink');
    Route::post('/password/update', 'AuthController@callResetPassword');

    // Articles
    Route::get('/articles', 'ArticleController@index');

    Route::middleware(['auth.header', 'auth:api'])->group(function () {
        // Get Logged in User
        Route::get('/user', function (Request $request) {
            return $request->user(); // returns the actual logged in user
        });

        // Articles
        Route::post('/articles', 'ArticleController@store');
        Route::get('/articles/{id}', 'ArticleController@show');
        Route::put('/articles/{id}', 'ArticleController@update');
        Route::delete('/articles/{id}', 'ArticleController@destroy');

        // Log Out
        Route::post('/logout', 'AuthController@logout');
    });
});

Пример контроллера, где Auth::user() равен нулю:

class ArticleController extends Controller
{
    public function index(Request $request)
    {
        $user = \auth()->user(); // null
        $user = Auth::user(); // null
        $user = $request->user(); // null
    }
}

В методе index я знаю, почему пользователь имеет значение null, поскольку маршрут не заключен в промежуточное ПО auth:api, но как мне получить аутентификационного пользователя в этом методе, даже если он не требуется.

Я уверен, что что-то упустил, но я не знаю что. Я буду рад предоставить больше кода.

РЕДАКТИРОВАТЬ: Мой auth.api промежуточное программное обеспечение:

class AuthenticationHeader
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (!$request->bearerToken()) {
            if ($request->hasCookie('auth_token')) {
                $token = $request->cookie('auth_token');
                $request->headers->add(['Authorization' => 'Bearer ' . $token]);
            }
        }
        return $next($request);
    }
}

1 Ответ

0 голосов
/ 11 января 2020

API Routes

Route::group(['prefix' => 'v1'], function() {

    // Authentication
    Route::post('/login', 'AuthController@login');
    Route::post('/register', 'AuthController@register');
    Route::post('/password/reset', 'AuthController@sendPasswordResetLink');
    Route::post('/password/update', 'AuthController@callResetPassword');

    // Articles
    Route::get('/articles', 'ArticleController@index');

    Route::middleware(['auth:api'])->group(function () {
        // Get Logged in User
        Route::get('/user', function (Request $request) {
            return $request->user(); // returns the actual logged in user
        });

        // Articles
        Route::post('/articles', 'ArticleController@store');
        Route::get('/articles/{id}', 'ArticleController@show');
        Route::put('/articles/{id}', 'ArticleController@update');
        Route::delete('/articles/{id}', 'ArticleController@destroy');

        // Log Out
        Route::post('/logout', 'AuthController@logout');
    });
});

Auth Controller

<?php

namespace App\Http\Controllers\Api;

use App\Mail\ResetPassword;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\Api\BaseController as BaseController;
use App\User;
use Illuminate\Support\Facades\Auth;
use Validator;
use Illuminate\Support\Facades\Password;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
use Illuminate\Foundation\Auth\ResetsPasswords;

//use Illuminate\Foundation\Auth\VerifiesEmails;
//use Illuminate\Auth\Events\Verified;

class AuthController extends BaseController
{
    use ResetsPasswords;

    /**
     * Authenticate api
     * @param  Request
     * @return \Illuminate\Http\Response
     */
    public function login(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|email',
            'password' => 'required',
        ]);

        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors(), 400);
        }

        $email = $request->input('email');
        $password = $request->input('password');

        if (Auth::attempt(['email' => $email, 'password' => $password])) {
            $user = Auth::user();
            if ($user->hasVerifiedEmail()) {
                $success['token'] = 'Bearer ' . $user->createToken('MyApp')->accessToken;

                $success['user'] = $user->only('id', 'name', 'email', 'avatar');

                return $this->sendResponse($success, 'User logged in successfully.');
            } else {
                return $this->sendError('Please verify your Email.', [], 400);
            }
        }

        return $this->sendError('Wrong Credentials.', [], 400);
    }

    /**
     * Register API
     * @param  Request
     * @return \Illuminate\Http\Response
     */
    public function register(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required',
            'email' => 'required|email',
            'password' => 'required',
            'c_password' => 'required|same:password',
            //'g-recaptcha-response' => 'required|captcha',
        ]);

        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors(), 400);
        }

        $name = $request->input('name');
        $email = $request->input('email');
        $password = $request->input('password');

        $user = User::where('email', $email)->first();

        if ($user) {
            return $this->sendError('This email address is already taken. Please try another.', [], 400);
        }

        $user = User::create([
            'name' => $name,
            'email' => $email,
            'password' => bcrypt($password)
        ]);

        $user->sendApiEmailVerificationNotification();


        return $this->sendResponse([], 'Please confirm yourself by clicking on verify user button sent to you on your email.');
    }

    /**
     * Send reset password email API
     * @param  Request
     * @return \Illuminate\Http\Response
     */
    public function sendPasswordResetLink(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|email',
        ]);

        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors(), 400);
        }

        $email = $request->input('email');


        $response = Password::sendResetLink(['email' => $email], function (Message $message) {
            $message->subject($this->getEmailSubject());
        });

        switch ($response) {
            case Password::RESET_LINK_SENT:
                return $this->sendResponse([], 'We have e-mailed your password reset link!');
            case Password::INVALID_USER:
                return $this->sendError('We can\'t find a user with that e-mail address.', [], 400);
        }
    }

    /**
     * Reset password action API
     * @param  Request
     * @return \Illuminate\Http\Response
     */
    public function callResetPassword(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'token' => 'required',
            'email' => 'required|email',
            'password' => 'required',
            'password_confirmation' => 'required|same:password',
        ]);

        if ($validator->fails()) {
            return $this->sendError('Validation Error.', $validator->errors(), 400);
        }

        // Here we will attempt to reset the user's password. If it is successful we
        // will update the password on an actual user model and persist it to the
        // database. Otherwise we will parse the error and return the response.
        $response = $this->broker()->reset(
            $this->credentials($request),
            function ($user, $password) {
                $this->resetPassword($user, $password);
            }
        );

        if ($response == Password::PASSWORD_RESET) {
            return $this->sendResponse([], 'User password has been successfully reset.');
        } else {
            return $this->sendError($response, [], 400);
        }
    }

    /**
     * Logout API
     * @param  Request
     * @return \Illuminate\Http\Response
     */
    public function logout(Request $request)
    {
        if (Auth::check()) {
            Auth::user()->oauthAcessTokens()->delete();
            return $this->sendResponse([], 'User logged out successfully.');
        }
    }
}

Базовый контроллер

<?php
namespace App\Http\Controllers\Api;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class BaseController extends Controller
{

    /**
    * success response method.
    *
    * @return \Illuminate\Http\Response
    */
    public function sendResponse($result, $message = null)
    {
        $response = [
            'success' => true,
            'data' => $result
        ];

        if (!empty($message)) {
            $response['message'] = $message;
        }

        return response()->json($response, 200);
    }


    /**
    * return error response.
    *
    * @return \Illuminate\Http\Response
    */
    public function sendError($error, $errorMessages = [], $code = 422)
    {
        $response = [
            'success' => false,
            'message' => $error,
        ];

        if (!empty($errorMessages)) {
            $response['data'] = $errorMessages;
        }

        return response()->json($response, $code);
    }
}
...