I want to allow only authenticated users to access some API routes. I use the default Laravel authentication system. After the default login, I want to be able to access a route, but I get the "Unauthenticated" message.
So, after login, I am redirect to the home route which uses the HomeComponent file. Here, using axios, I am making a call to the step API route where I am trying to get the id of the authenticated user, but instead I receive an error message. What am I doing wrong?
api.php
Route::middleware('auth:api')->group(function () {
Route::get('application/step', ['as' => 'application.step', 'uses' => 'ApplicationController#step']);
});
ApplicationController.php
public function step() {
print_r(auth()->user());
die('---');
// code to get authenticated user step
return json_encode(array('step' => 7));
}
LoginController.php
public function login(Request $request)
{
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:6'
]);
$user = User::where('email', $request->email)->firstOrFail();
if ($user && !$user->isAdmin()) {
if (Auth::attempt(['email' => $request->email, 'password' => $request->password], true)) {
$token = $user->createToken('TokenName')->token;
$token->save();
return redirect()->route('home');
}
else {
return back()->withInput($request->only('email'));
}
}
return back()->withInput($request->only('email'))->withErrors(['denied' => 'You are not allowed to access this page.']);
}
HomeComponent.vue
...
getStep() {
axios.get("/api/application/step")
.then((response) => {
this.step = response.data.step;
})
.catch((err) => {
console.log('Cannot get step', err);
});
}
auth:api middleware only work with Passport. This auth:api middleware check valid access token.
And I think you are not using passport for login
composer require laravel/passport
In your case you can only use auth middleware instead auth:api
Related
i have a log in form in my front end (vue) when users log in, in vue i can get back data of logged in user perfectly fine through
axios.get('http://127.0.0.1:8000/api/user').then((response)=>{
this.userData = response.data;
However in my backend when i try to bring back the logged in user though
if ($request->user('sanctum')) {
return "auth";
} else {
return "guest";
}
it returns guest i dont know why!!!!
vue code:
async login(){
axios.post('http://127.0.0.1:8000/api/login', this.form).then((response) =>{
localStorage.setItem('token', response.data);
axios.defaults.headers.common['Authorization'] = `Bearer ${response.data.token}`;
this.$router.push('/');
} )
.catch ((error) =>{
console.log(error.response.data.errors);
})
},
laravel auth controller :
public function loginn(Request $request){
$request->validate([
'email' => 'required',
'password' => 'required',
]);
$user = User::where('email', $request->email)->first();
if (! $user || ! Hash::check($request->password, $user->password)) {
throw ValidationException::withMessages([
'email' => ['The provided credentials are incorrect.'],
]);
}
return $user->createToken("token")->plainTextToken;
return response()->json([
'token' => $token,
'type' => 'bearer',
'expires_in' => auth()->factory()->getTTL() * 60
]);
api.php
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
Route::post('/signup', [authcontroller::class, 'signupp']);
Route::post('/login', [authcontroller::class, 'loginn'])->name('login');;
Route::post('/logout',[authcontroller::class, 'logout'])->middleware('auth:sanctum');
I haved this problem.
This problem is for .env in backend laravel and get csrf front
remembering that the localhost address must be either localhost or 127.0.0.1 amd get csrf before
axios.get('/sanctum/csrf-cookie').then(response => {
// Login...
});
.env
SESSION_DOMAIN=127.0.0.1
SACTUM_STATEFUL_DOMAINS=127.0.01:PORT
I have created a REST API with LARAVEL SANCTUM. I have tested api on postman and it works as expected but when mobile developer uses it on ionic app, it returns for login "TOKEN MISMATCH".
Here is my API route
Route::post('/register', [ApiController::class, 'register']);
Route::post('/login', [ApiController::class, 'login']);
Here is the ApiController for login
public function login(Request $request){
$fields = $request->validate([
'email' => 'required|string|email|max:255',
'password' => 'required|string|min:8'
]);
//validate login parameters
//check email
$user = User::where('email', $fields['email'])->first();
//check password
if(!$user || !Hash::check($fields['password'], $user->password)){
return response([
'message' => 'Invalid Credentials'
], 401);
}
$token = $user->createToken('myapptoken')->plainTextToken;
//return $user->createToken($request->device_name)->plainTextToken;
$response = [
'user' => $user,
'token' =>$token,
];
return response($response, 201);
}
EndPoint: https://findajob.ng/api/login
Email:johndeo1#gmail.com
Password: 12345678
This might not be a problem from backend, but in other-hand, if everything work in postman, you might try to:
Change support_credentials in config\cors to true.
Add withCredential header to front-end.
I am trying to login though API. My code is like below.
public function store(LoginRequest $request)
{
$response = Http::post('http://moretext/login', [
'email' => $request->email,
'password' => $request->password,
]);
$session_token = str_replace("Bearer ", "", $response->json()['access_token']); // I am getting Token here
if ($session_token) {
Session::put('SesTok', $session_token);
return redirect('/dashboard'); //This redirect is not working.
} else {
return redirect('/login')->withErrors('Login is not successful.');
}
}
I have below the code in route.php file.
Route::get('/dashboard', function () {
return view('dashboard');
});
there's no redirect throw apis
api except response json
if you want to redirect don't call as api
do in web routes and it will work fine
I created a user auth system based on Passport in my app and now I have some troubles. When I send a token, my details() method returned all app users instead of specific one. I paste my code to show exactly what is going on.
Login method:
public function login(){
if(Auth::attempt(['email' => request('email'), 'password' => request('password')])){
$user = Auth::user();
$success['token'] = $user->createToken('myapp')->accessToken;
$user->api_token = $success['token'];
$user->save();
return response()->json(['user' => $success], $this->successStatus);
}
else{
return response()->json(['error'=>'Unauthorised'], 401);
}
}
It return something like that:
{
"user": {
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImFjMzEwM2UyMzIwNGIxMjg3M2E3ZWMyZmUyNGJkNDEzMTQyN2I1ZWUzMWRjOGFhZjRhMzcyMDQzM2ZmNGJiZGJjZGU3ZjQ1ZjZkNzZmMGRkIn0.eyJhdWQiOiIxIiwianRpIjoiYWMzMTAzZTIzMjA0YjEyODczYTdlYzJmZTI0YmQ0MTMxNDI3YjVlZTMxZGM4YWFmNGEzNzIwNDMzZmY0YmJkYmNkZTdmNDVmNmQ3NmYwZGQiLCJpYXQiOjE1NTIxMzIyODMsIm5iZiI6MTU1MjEzMjI4MywiZXhwIjoxNTgzNzU0NjgzLCJzdWIiOiIxOCIsInNjb3BlcyI6W119.LmwTCSlRTrZ9pq01JK6tfsx5yjjA9qfidTws-0_vVc-UsFKQOJSk-K1uAYMR5gd0SQzC8VyG8bIJLVdPZbm5ggXkk-itN1bHEdZPFT7zdx7rOTFVF1ri9-chZIDL6nElosk3SOw_1QwuwOxiMHBB7ss9ItPHrtwkNEMxpeh16henknIZVYct0Vn1grztdnh7EJCM9SkKjIxqF0yozuw-wsN-UmsLvNoFZkOFWuNCPC9Mawx_ip2VBD26mwcxzTgD1XFwRloTCtDOAZfQ4DfgS_YuuXEPn8pfrkp92C1lxGXp09Wu0ZdzFaIf8LWEQXCgwlqvsVuFSnKt3lGyEPuHuJc_DjZZTcWgjslVQr7RhEqWQmRK2xlJpiAcZyWoI1vhfYLmullr1vf7nGCoRsp3UDZB64J2oPVjomcClEfseAKQbIq_9roKxIGjTeYdaF2vwHCosaxzrak7AqBHkze-z5cL8ix9G6rWBeg4sDUPhiLDgrgHK4ywxBqHMyto-Ywak56pzq1767r4reunDyNYDhLwSt0IiK1Hmx7ZQ9j6_EWy3NLf1oy7eGc33bj7eQNusbEa0TfcXujNK299RAEnTFLEc4kuS_otHzGrwSvOx2zYPsZkctZYn19YoyKaeP7hM1ek0zfIlGXsxQI84osPl91U7PHqAufIK6YJeizcik0"
}
}
When I have my token for specific user I send that token to details().
Details method:
public function details(Request $request)
{
$userData = $request->user()->with('kids')->with('hobbies')->with('conversations')->get();
return response()->json(['user' => $userData], $this->successStatus);
}
Here is my api.php route file:
Route::group(['middleware' => 'auth:api'], function(){
Route::get('details', 'UserController#details');
});
Route::post('login', 'UserController#login');
Route::post('register', 'UserController#register');
I don't know why my details method return all app users. Do you have any advice how I can fix that? I really appreciate any help with that trouble.
I'm trying to figure out how to test my Passport-driven logout function, which looks like this:
public function logout() {
$accessToken = auth()->user()->token();
$refreshToken = DB::table('oauth_refresh_tokens')
->where('access_token_id', $accessToken->id)
->update([
'revoked' => true
]);
$accessToken->revoke();
return response()->json(['status' => 200]);
}
I am using the Passport actingAs helper in setting up the response.
Passport::actingAs(
$user,
['read write']
);
$response = $this->post('/logout')
->assertStatus(200);
The test fails, as the code gives a 500 error, as auth()->user()->token() is ... empty-ish? $accessToken->id is 0, for example, which it shouldn't be, which means the code fails.
What I'm not sure about is if this is expected behavior because of how Passport's actingAs helper works and I can't actually test the logout function, or if there's something wrong with my logout function. Halp!
My routes:
Route::post('login', 'Auth\LoginController#login');
Route::group(['middleware' => 'auth:api'], function() {
Route::post('logout', 'Auth\LoginController#logout');
});
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
JsonApi::register('v1', ['namespace' => 'Api'], function (Api $api, $router) {
$api->resource('training-locations');
$api->resource('courses');
});
ETA: My login function, if it's helpful:
public function login(Request $request, Client $client){
$this->validateLogin($request);
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
$response = $client->post(config('app.url') . '/oauth/token', [
'form_params' => [
'client_id' => config('auth.proxy.client_id'),
'client_secret' => config('auth.proxy.client_secret'),
'grant_type' => config('auth.proxy.grant_type'),
'username' => $request->email,
'password' => $request->password,
'scopes' => '[read write]'
]
]);
if ($response->getStatusCode() === 200) {
$this->clearLoginAttempts($request);
return response($response->getBody()->getContents(), $response->getStatusCode());
}
$this->incrementLoginAttempts($request);
return response($response->getBody()->getContents(), $response->getStatusCode());
}
In order to investigate if this is actually an issue, I tried hitting the endpoint via Postman. It gets into the function, but it does not find the auth()->user(). I tried some other endpoints using the same route group, and it was able to find the auth()->user() with them. What might cause it to go missing like that?
It's a little late, but maybe someone will find it helpful. In order to test the logout function you have provided you'll need to pass the token as authorization header.
$response = $this->post('/logout', [], ['Authorization' => 'Bearer ' . $token])
->assertStatus(200);
I'm not sure why, but the access token can't be retrieved with $user->token() when using actingAs, but it can be retrieved with $user->tokens()->first()
.