0

I'm using Passport for my authentication system.

I'm not sure why Auth::check()'s returning false even though I'm using the correct credentials to login. I can verify that the login works because if I type in a wrong email and password, the login fails.

I've been stuck on this for a few days and not sure what's wrong.

public function login(Request $request) {

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

    if (Hash::check($request->password, $user->password)) {
        $loginToken = $user->createToken('MyApp')->accessToken;
        dd(Auth::check());
        return response()->json([
            'message' => 'Successfully logged in',
            'loginToken' => $loginToken
        ]);
    }

    return $this->sendError('Unauthorized.', ['error' => 'Unauthorized']);
}

Here's api.php:

Route::group(['middleware' => 'api'], function(){
   Route::post('/login', [RegisterController::class, 'login']);
});

Here's auth.php:

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

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

    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

Here's login:

const handleSubmitLogin = (e) => {
    e.preventDefault();
    let dataLogin = {
        'email': email,
        'password': password,
    };

    JSON.stringify(dataLogin);

    axios.post('http://site.test/api/login', dataLogin)
        .then(resp => {
            console.log(resp);
            history.push('/gallery');
        }).catch(error => {
        console.log(error);
    });

    setUserState('myState');

};

dd() response:

    Illuminate\Http\Client\Response {#329
  #response: GuzzleHttp\Psr7\Response {#365
    -reasonPhrase: "Unauthorized"
    -statusCode: 401
    -headers: array:8 [
      "Server" => array:1 [
        0 => "nginx/1.18.0 (Ubuntu)"
      ]
      "Content-Type" => array:1 [
        0 => "application/json"
      ]
      "Transfer-Encoding" => array:1 [
        0 => "chunked"
      ]
      "Connection" => array:1 [
        0 => "keep-alive"
      ]
      "Cache-Control" => array:1 [
        0 => "no-cache, private"
      ]
      "Date" => array:1 [
        0 => "Sun, 26 Sep 2021 16:06:57 GMT"
      ]
      "X-RateLimit-Limit" => array:1 [
        0 => "60"
      ]
      "X-RateLimit-Remaining" => array:1 [
        0 => "57"
      ]
    ]
    -headerNames: array:8 [
      "server" => "Server"
      "content-type" => "Content-Type"
      "transfer-encoding" => "Transfer-Encoding"
      "connection" => "Connection"
      "cache-control" => "Cache-Control"
      "date" => "Date"
      "x-ratelimit-limit" => "X-RateLimit-Limit"
      "x-ratelimit-remaining" => "X-RateLimit-Remaining"
    ]
    -protocol: "1.1"
    -stream: GuzzleHttp\Psr7\Stream {#363
      -stream: stream resource @9
        wrapper_type: "PHP"
        stream_type: "TEMP"
        mode: "w+b"
        unread_bytes: 0
        seekable: true
        uri: "php://temp"
        options: []
      }
      -size: null
      -seekable: true
      -readable: true
      -writable: true
      -uri: "php://temp"
      -customMetadata: []
    }
  }
  #decoded: null
  +"cookies": GuzzleHttp\Cookie\CookieJar {#343
    -cookies: []
    -strictMode: false
  }
  +"transferStats": GuzzleHttp\TransferStats {#364
    -request: GuzzleHttp\Psr7\Request {#359
      -method: "POST"
      -requestTarget: null
      -uri: GuzzleHttp\Psr7\Uri {#349
        -scheme: "http"
        -userInfo: ""
        -host: "site.test"
        -port: null
        -path: "/oauth/token"
        -query: ""
        -fragment: ""
      }
      -headers: array:4 [
        "Content-Length" => array:1 [
          0 => "115"
        ]
        "User-Agent" => array:1 [
          0 => "GuzzleHttp/7"
        ]
        "Host" => array:1 [
          0 => "site.test"
        ]
        "Content-Type" => array:1 [
          0 => "application/x-www-form-urlencoded"
        ]
      ]
      -headerNames: array:4 [
        "content-length" => "Content-Length"
        "user-agent" => "User-Agent"
        "host" => "Host"
        "content-type" => "Content-Type"
      ]
      -protocol: "1.1"
      -stream: GuzzleHttp\Psr7\Stream {#350
        -stream: stream resource @7
          wrapper_type: "PHP"
          stream_type: "TEMP"
          mode: "w+b"
          unread_bytes: 0
          seekable: true
          uri: "php://temp"
          options: []
        }
        -size: 115
        -seekable: true
        -readable: true
        -writable: true
        -uri: "php://temp"
        -customMetadata: []
      }
    }
    -response: GuzzleHttp\Psr7\Response {#365}
    -transferTime: 0.080212
    -handlerStats: array:38 [
      "url" => "http://site.test/oauth/token"
      "content_type" => "application/json"
      "http_code" => 401
      "header_size" => 265
      "request_size" => 260
      "filetime" => -1
      "ssl_verify_result" => 0
      "redirect_count" => 0
      "total_time" => 0.080212
      "namelookup_time" => 0.000237
      "connect_time" => 0.00033
      "pretransfer_time" => 0.000366
      "size_upload" => 115.0
      "size_download" => 118.0
      "speed_download" => 1475.0
      "speed_upload" => 1437.0
      "download_content_length" => -1.0
      "upload_content_length" => 115.0
      "starttransfer_time" => 0.078857
      "redirect_time" => 0.0
      "redirect_url" => ""
      "primary_ip" => "127.0.0.1"
      "certinfo" => []
      "primary_port" => 80
      "local_ip" => "127.0.0.1"
      "local_port" => 59814
      "http_version" => 2
      "protocol" => 1
      "ssl_verifyresult" => 0
      "scheme" => "HTTP"
      "appconnect_time_us" => 0
      "connect_time_us" => 330
      "namelookup_time_us" => 237
      "pretransfer_time_us" => 366
      "redirect_time_us" => 0
      "starttransfer_time_us" => 78857
      "total_time_us" => 80212
      "appconnect_time" => 0.0
    ]
    -handlerErrorData: 0
  }
}
sp92
  • 873
  • 1
  • 6
  • 17
  • `Hash::check` doesn't log you in it just checks the password. Maybe try doing `Auth::attempt([ 'email' => $request->email, 'password' => $request->password ])` instead. That way you both get the authentication check but also get signed in the default guard – apokryfos Sep 26 '21 at 14:17
  • 1
    @apokryfos `Auth::attempt()` doesn't exist when using Passport, it will throw an error. – Anthony Aslangul Sep 26 '21 at 14:18

2 Answers2

1

Besides @Anthony Aslangul answer is right, I see that your login is not correct.

As per Laravel Passport Documentation

Once you have created a password grant client, you may request an access token by issuing a POST request to the /oauth/token route with the user's email address and password.

Saying that, the right way to login should be like this, withing your login function

$response = Http::asForm()->post('http://site.test/oauth/token', [
    'grant_type' => 'password',
    'client_id' => 'client-id',
    'client_secret' => 'client-secret',
    'username' => $request->email,
    'password' => $request->password,
    'scope' => '',
]);

$result = $response->getBody()->getContents();
$access_token = json_decode($result)->access_token;
$refresh_token = json_decode($result)->refresh_token;

return response()->json([
   'access_token' => $access_token,
   'refresh_token' => $refresh_token
], $response->getStatusCode());

In addition, in order to check if your user is logged in, you can try by specifying your guard such as

Auth::guard('api')->check()

These also may help you:

how to check if user is authenticated with passport (get user from token using laravel-passport)

Laravel Passport Token doesn't return series of code

Luciano
  • 2,052
  • 1
  • 16
  • 26
  • gotcha thanks for this! But for some reason, `access_token` is returning `null` and I'm not sure why – sp92 Sep 26 '21 at 15:21
  • Can you `dd()` your `$response` ? Maybe you don't need to do `json_decode()` and just get tokens by doing `$response->access_token;` and `$response->refresh_token;` – Luciano Sep 26 '21 at 15:54
  • Sorry, you can scratch my original comment above. the `dd()` of my `$response` returns `"message": "Undefined property: Illuminate\\Http\\Client\\Response::$access_token"`. – sp92 Sep 26 '21 at 15:59
  • Try to `dd()` immediately after `$response = Http::asForm()->post()` to confirm that your login is done right. From that, you will figure out how to get tokens – Luciano Sep 26 '21 at 16:03
  • Good point. I `dd()`'d right after the `$response = Http::asForm()->post()`, I'm getting a `401` error. check my original post for the `dd` output. – sp92 Sep 26 '21 at 16:09
  • Well, everything points that you have the wrong `client_id` or `client_secret` values. If your credentials (email/password) were wrong, you should get a `400` error code. But your request is returning `401` which means that you are facing a passport connection issue. – Luciano Sep 26 '21 at 16:18
  • BTW, why do you have your login route within `api` middleware? Shouldn't be publicly accessible? Try moving your login route out of the middleware group – Luciano Sep 26 '21 at 16:22
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/237529/discussion-between-sp92-and-luciano). – sp92 Sep 26 '21 at 16:29
0

Technically you are not logged in at this point.

You have checked that the user exists, then you have created a new token for this user, but that's all, the token has not been used to authenticate anyone.

In order to authenticate the user, you will need to make a request with the Authorization header setup: Authorization: Bearer $the_token_you_created.

The usual workflow for api tokens is:

  • Make a request to the server with username and password
  • The server sends back a token in the response
  • You use this token for every subsequent api calls (you can store it in the local storage or a cookie)

However, you are using Passport... which don't make sense since you don't seem to need OAuth2 support. You should better take a look at Sanctum with api tokens.

Anthony Aslangul
  • 3,589
  • 2
  • 20
  • 30
  • Makes sense. But the user (my test user) has registered a while ago so how can I retrieve that token to use the authorization header setup? What's a good way to go about doing this? – sp92 Sep 26 '21 at 14:00
  • I have updated my answer to give you some hints, I hope it will help. To clarify, Passport is a good package, but it is designed for oauth2 (which is what "connect with google/steam/twitter/..." use). In your case and from what I understand of your code, you are more in a first party SPA / API relationship, that's why Sanctum is more suited here. – Anthony Aslangul Sep 26 '21 at 14:16