Showing only current authenticated user orders in laravel 5.8 - php

I'm creating an API for the android developer to be able to show the orders made by user.My code makes any user show any product, what I want is only showing orders made by authenticated user
I've protected the route like that:
Route::middleware('auth:api')->group( function () {
Route::resource('orders', 'API\OrdersController');
});
and I use the following headers on the request:
'headers' => [ 'Accept' => 'application/json', 'Authorization' => 'Bearer '.$accessToken,]
here is the controller code of the show($id) method
public function show($id)
{
$user = Auth::id();
$Orders = Orders::where('id',$id)->where('order_shopper_id', $user)->get();
if (is_null($Orders) || empty($Orders)) {
return $this->sendError('Orders not found.');
}
return $this->sendResponse($Orders->toArray(), 'Orders retrieved successfully.');
}
it works but when for example I try to access order number "2" and the authenticated user didn't create that order, it still returns success with empty data.
All I want is, "Select Order Number (#) but make sure that the logged in user had created that order not someone else, if not return unAuthenticated"
Thank you in advance.

The QueryBuilder::get() method returns a collection, a empty collection is still a collection object, so the $Orders never will be null or empty.
Try:
if (!$Orders->count()) {
return $this->sendError('Orders not found.');
}

If you authenticate the user based on token, you have to get the authenticated user id this way:
$user = Auth::guard('api')->id();
And change the if statement as #kiske has said.

try
if($Orders->isEmpty()){
return $this->sendError('Orders not found.');
}

Related

How can i fix "not logged in" error in laravel even after logging in?

Im making a gym app on laravel 9 as an api. The app will have a normal user and also an admin which has access to certain files that a normal user doesnt. For that i created a middleware but im facing a few problems there.
See even after i log in, when i try using a route protected by my isAdmin middleware, i get the error: Log in to gain access. This is the Login function:
public function login(Request $request)
{
$creds = $request->validate([
'email' => 'required|email|string|exists:users,email',
'password' => ['required']
]);
if (!Auth::attempt($creds)) {
return response([ 'message' => 'Provided email or password is incorrect' ], 422);
}
/** #var \App\Models\User $user */
$user = Auth::user();
Auth::login($user);
$token = $user->createToken('main')->plainTextToken;
return response(compact('user', 'token'))->header('Authorization', 'Bearer '.$token);
}
and then this is the middleware
public function handle(Request $request, Closure $next)
{
if (Auth::check()) {
$user = Auth::guard('auth')->user();
dd($user);
if ($user->role == 1) {
return $next($request);
} else{
return response(['msg'=>'You are not authorized for this route!']);
}
} else{
return response(['msg'=>'Log In to gain access!']);
}
return $next($request);
}
Im pretty sure the problem has to do with the token either not being sent or being stored properly, but i cant seem to find where the problem is. Also this is what im doing in Postman if that would help:
Login
Add Recipe (this is a route guarded by the middleware)
And also here are their headers respectively
Also i dont know if this is info that will help but i have to manually write the that bearer token for it to show up. (im a beginner so idk how it should be done)

Laravel how to get auth user id on cronjob

I run a cronjob every minute and data returne, i save on db in a table notification. But here i need to save also user_id. I mean i know we can not find Auth::user()->id on cronjob but how can we get this user id?
public function handle(ReminderEventServices $reminderServices)
{
// return 0;
// $getLastReminders = $reminderServices->ReminderEvent();
$getLastReminders = Reminder::orderBy('id', 'DESC')->get();
return app('App\Http\Controllers\NotificationController')->store($getLastReminders);
}
I have send request to Notification controller , hoping there i can use there Auth but i was wrong.
public function store($getLastReminders)
{
$user_id = Auth::user()->id;
foreach($getLastReminders as $reminder) {
if (!Notification::where('title', $reminder->title)->exists()) {
$notification = Notification::create([
'title' => $reminder->title,
'user_id' => $user_id,
'description' => $reminder->description,
'remindTime' => $reminder->remindTime
]);
}
event(new ReminderEvent($reminder));
}
}
You should try another approach - the cron job is not supposed to handle users in that way. Consider trying an event listener or an observer instead. I've included the link to Laravels documentation on events for your convienience.

Angular/Laravel - getting 'No query results for model [App\Models\User]' error

I'm working with Laravel and Angular. I want to display the authenticated user's data. I'm getting datas from Laravel with JSON and I'm using this code for the user datas.
const headers = new HttpHeaders({
Authorization: `Bearer ${localStorage.getItem('token')}`
});
this.http.get('http://127.0.0.1:8000/api/user', {headers}).subscribe(
result => (this.user = result, console.log(result))
);
It's working but after a certain time this code does not work and I'm getting the error in console.
No query results for model [App\Models\User]
127.0.0.1:8000/api/user 404 (Not Found)
What am I missing?
UserController
public function user() {
$user = User::where('id', Auth::id())->firstOrfail();
return response()->json($user);
}
api.php
Route::get('/user', [UserController::class, 'user']);
maybe your session is ending and that's why Auth::id() returns empty and can't find your username

Call to undefined method Laravel\Socialite\Two\User::createToken()

In a laravel 5.8 API project, I want users to login via their social accounts. So far I have been able to use Socialite to retrieve user info from the provider and use it to create a new user record. But when I try to have the user log in again, it throws up the following error
Call to undefined method Laravel\Socialite\Two\User::createToken()
Here's the code I am working with
<?php
namespace App\Http\Controllers;
use App\User;
use Socialite;
use App\SocialAccount;
use App\Http\Resources\UserResource;
class SocialAuthController extends Controller
{
...
public function handleProviderCallback($provider)
{
$socialUser = Socialite::driver($provider)->stateless()->user();
$userSocialAccount = SocialAccount::where('provider_id', $socialUser->id)->where('provider_name', $provider)->first();
/*
if account exist, return the social account user
else create the user account, then return the new user
*/
if ($userSocialAccount) {
// generate access token for use
$token = $socialUser->createToken('********')->accessToken;
// return access token & user data
return response()->json([
'token' => $token,
'user' => (new UserResource($userSocialAccount))
]);
} else {
$user = User::create([
'firstname' => $socialUser->name,
'lastname' => $socialUser->name,
'username' => $socialUser->email,
'email_verified_at' => now()
]);
if ($user) {
SocialAccount::create([
'provider_id' => $socialUser->id,
'provider_name' => $provider,
'user_id' => $user->id
]);
}
// assign passport token to user
$token = $user->createToken('********')->accessToken;
return response()->json(['token' => $token, 'user' => new UserResource($user)]);
}
}
}
I haven't been able to spot the reason why I am getting the error when the user attempts a second login but there is no error if it's the first time the user logs in with a social account.
Why does it complain about Laravel\Socialite\Two\User::createToken() method? If I try adding this line use Laravel\Socialite\Two\User vscode intelephsense flags it as a duplicate of App\User so what is really going on in my code?
I think your last sentence hits the problem: the Laravel\Socialite\Two\User and App\User are two fully separate entities.
The Socialite::driver($provider)->stateless()->user() provides you with a Socialite User whereas User::create creates an App\User.
The second $token = $user->createToken('********')->accessToken; works because App\User has the createToken function and the other does not.
First of all the problem I was having with having a token generated by passport for users authentication after the first social login was because I was calling the createToken method on the user returned by Socialite. As explained by #JorisJ1 Socialite does not have the createToken function so my initial code threw an error.
Here's how I fixed it
public function handleProviderCallback($provider)
{
// retrieve social user info
$socialUser = Socialite::driver($provider)->stateless()->user();
// check if social user provider record is stored
$userSocialAccount = SocialAccount::where('provider_id', $socialUser->id)->where('provider_name', $provider)->first();
if ($userSocialAccount) {
// retrieve the user from users store
$user = User::find($userSocialAccount->user_id);
// assign access token to user
$token = $user->createToken('Pramopro')->accessToken;
// return access token & user data
return response()->json([
'token' => $token,
'user' => (new UserResource($user))
]);
} else {
...
}
}
Comments are welcomed if there is a better way for adding social authentication to API.

Session doesn't get stored permanently Laravel 5.5

I am creating a small blog-esque site. This site has basically 3 permission levels: Admin (can edit/remove any post AND create a user), a user (can upload posts and pictures) and a guest (no account needed, can just browse the posts).
I am using Laravel 5.5 to create this site.
When someone logs in, after being authenticated, I store their username and user type (admin/user) in a session and after login, they are redirected to their respective pages, as shown in the below code.
I overrided the 'authenticated' method in the AuthenticatesUsers trait:
LoginController.php
protected function authenticated(Request $request, $user)
{
$type = $user->toArray()['type'];//get user type (admin/user)
$username = $user->toArray()['username'];
$request->session()->put('type', $type);
$request->session()->put('username', $username);
if ( $type == 'admin' ) {
return redirect()->route('admin_home');
}
return redirect()->route('user_home');
}
The above code works and my user is redirected upon successful login.
However, if my user accesses the site home (localhost:8000/) I want the user to see the admin home page or user home page (localhost:8000/ just shows the homepage for a not logged in guest)
I did that using the following codes:
Web.php
Route::get('/', 'ContentController#publicHome');
Route::middleware('auth')->group(function(){
Route::get('/user/home', 'ContentController#userHome')->name('user_home');
Route::get('/admin/home', 'ContentController#adminHome')->name('admin_home');
});
Filtering whether user is logged in or just a guest:
ContentController - publicHome function
public function publicHome(Request $request){
$data = [];
$data['home'] = 1;
if($request->session()->has('type')){
switch ($request->session()->pull('type')){
case 'admin':
return redirect()->route('admin_home');
case 'user':
return redirect()->route('user_home');
}
}
return view('public.home', $data);
}
ContentController - userHome function
public function userHome(Request $request){
$data = [];
$data['username'] = $this->getUsername($request);
$data['type'] = $this->getUserType($request);
// dd($data); explanation for this line below
return view('user.home', $data);
}
ContentController - adminHome function
public function adminHome(Request $request){
$data = [];
$data['username'] = $this->getUsername($request);
$data['type'] = $this->getUserType($request);
//dd($data);
return view('admin.home', $data);
}
ContentController - getUsername & getUserType functions
public function getUsername(Request $request){
return $request->session()->has('username') ? $request->session()->pull('username') : 'username not set';
}
public function getUserType(Request $request){
return $request->session()->has('type') ? $request->session()->pull('type') : 'user type not set';
}
I used the dump and die function to see the $data[] array before loading the view
Right after successful login:
array:2 [▼
"username" => "testAdmin"
"type" => "admin"
] //works correctly, session variables seem to be set
So when I type in localhost:8000/ I expect to be redirected to /admin/home (or /user/home depending on login) but I just get sent to localhost:8000/ as if I am not logged in. So now when I manually type in /admin/home I get the following dump and die output:
array:2 [▼
"username" => "username not set"
"type" => "user type not set"
]
If you are using $request->session()->pull('username') it fetches the data i.e. username from session and deletes it at the same time.
Instead, you can use laravel's helper method session() to get data without deleting it. So now you can use session('username') to get the username.
For more info refer : https://laravel.com/docs/5.5/session
Some Suggestions:
You could have used laravel's internal Auth library to build the login system which already has lot many features you don't need to code again. https://laravel.com/docs/5.5/authentication
You can also have multi-user authentication (admin & regular user). Refer this link if you want to implement so: https://scotch.io/tutorials/user-authorization-in-laravel-54-with-spatie-laravel-permission

Categories