I have an Vue + Laravel application. Here I am using laravel API routes to get the data. For the API auth I am using JWT from this tutorial: https://blog.logrocket.com/implementing-jwt-authentication-laravel-9/
Now I am getting:
{"message":"Unauthenticated."}
error message whne I access to this API route: http://localhost:3000/api/countries
Country.php (Model)
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Country extends Model
{
use HasFactory;
protected $table = 'countries';
protected $primaryKey = 'id_country';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'country_name' ,
'code' ,
];
}
CountryController.php (Controller)
<?php
namespace App\Http\Controllers;
use App\Models\Country;
use Illuminate\Http\Request;
class CountryController extends Controller
{
public function __construct()
{
$this->middleware('auth:api');
}
/**
* #return \Illuminate\Http\JsonResponse
*/
public function countries()
{
$country = Country::get();
return response()->json($country, 200);
}
}
api.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Auth\AuthController;
use App\Http\Controllers\CountryController;
Route::controller(CountryController::class)->group(function () {
Route::get('countries', 'countries')->name("countries");
});
Can you tell me what is wrong here and how can I solve it?
Related
Hello i have try to do permisssion and role in laravel 9 but i have a error .
User model
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable implements MustVerifyEmail
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
'secretword',
];
/**
* The attributes that should be hidden for serialization.
*
* #var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* #var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function roles()
{
return $this
->belongsToMany('App\Role')
->withTimestamps();
}
public function users()
{
return $this
->belongsToMany('App\User')
->withTimestamps();
}
public function authorizeRoles($roles)
{
if ($this->hasAnyRole($roles)) {
return true;
}
abort(401, 'This action is unauthorized.');
}
public function hasAnyRole($roles)
{
if (is_array($roles)) {
foreach ($roles as $role) {
if ($this->hasRole($role)) {
return true;
}
}
} else {
if ($this->hasRole($roles)) {
return true;
}
}
return false;
}
public function hasRole($role)
{
if ($this->roles()->where('name', $role)->first()) {
return true;
}
return false;
}
};
Role model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
use HasFactory;
}
AdminController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class AdminController extends Controller
{
public function __construct()
{
$this->middleware('auth');
$this->middleware('role:ROLE_ADMIN');
}
public function index()
{
return view('admin.home');
}
}
SuperAdminController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class SuperAdminController extends Controller
{
public function __construct()
{
$this->middleware('auth');
$this->middleware('role:ROLE_SUPERADMIN');
}
public function index()
{
return view('superadmin.home');
}
}
web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('auth/login');
});
Auth::routes(['verify' => true]);
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Route::get('/admin', [App\Http\Controllers\AdminController::class, 'index']);
Route::get('/superadmin', [App\Http\Controllers\SuperAdminController::class, 'index']);
Route::resource('posts', PostController::class);
app / Http / Middleware / CheckRole.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class CheckRole
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* #return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next)
{
if (! $request->user()->hasRole($role)) {
abort(401, 'This action is unauthorized.');
}
return $next($request);
}
}
I try to do permissions and roles in laravel 9.And when i want to go /admin i have this error and show me this file i want to know how can i resolve this error for all good work?
You need pass and accept the parameter of role, in middleware.
Your middleware
public function handle(Request $request, Closure $next, string $role)
If you are using route for middleware then
Route::resource(...)->middleware('middlewareName:roleName');
If controller being used
$this->middleware(\App\Http\Middleware\CheckRole::class.':roleName')
To send argument to the middleware, use : after the middleware name. To send multiple argument, separate the arguments with ,.
I strongly recommend using Policy classes for this. Then you can simply use the can middleware.
More info here: https://laravel.com/docs/9.x/authorization#creating-policies
Your models basically would have their own policy classes per model, then you can fine tune exactly what users can do based on what their role is.
No need to reinvent the wheel here.
I am trying ORM one to one relationship. I dont know why it cant recognize model class phone.
code as follows.
Phone.php
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function Phone(){
return $this->hasOne('app\Models\Phone');
}
}
Phone.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Phone extends Model
{
use HasFactory;
protected $table = "phones";
public function User(){
return $this->belongsTo('app\Models\User');
}
}
UserController.php
<?php
namespace App\Http\Controllers;
use App\Models\Phone;
use App\Models\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function insert(){
$user = new User();
$user->name = 'BBB';
$user->email = 'bbb#mail.com';
$user->password = 'bbb#mail.com';
$user->save();
$phone = new Phone();
$phone->number = "445566";
$user->Phone()->save($phone);
return "RECORDS ADDED";
}
public function show($id){
$phone = User::find($id)->phone;
return $phone;
}
}
web.php
<?php
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
});
Route::get('insert',[\App\Http\Controllers\UserController::class,'insert'])->name('user.insert');
Route::get('show/{id}',[\App\Http\Controllers\UserController::class,'show'])->name('user.show');
You need to fix this
public function User(){
return $this->belongsTo('App\Models\User');
}
here fix namespace app to App like that you need to fix all
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function Phone(){
return $this->hasOne('App\Models\Phone');
//Better to use ::class notation for greater benefits with IDE
//return $this->hasOne(Phone::class);
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Phone extends Model
{
use HasFactory;
protected $table = "phones";
public function User(){
return $this->belongsTo('App\Models\User');
//Better to use ::class notation for greater benefits with IDE
//return $this->hasOne(User::class);
}
}
Folder/directory is app but the namespace is App
So need to change app\Models\Phone and app\Models\User to App\Models\Phone and App\Models\User
Better yet, use ::class notation for greater benefits with IDE - like easy navigation - not possible with string literals.
So instead of string literal App\Models\Phone import use App\Models\Phone statement and the Phone::class
Similarly for User import use App\Models\User and then use User::class
I'm trying to generate a token to authenticate users in my Controller the following way:
namespace App\Http\Controllers\API;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
class AuthController extends Controller
{
public function login()
{
if (Auth::attempt(['email' => request('email'), 'password' => request('password')])) {
$user = Auth::user();
$success['token'] = $user->createToken('myApp')->accessToken;
dd($success['token']);
}
}
Currently, I'm just trying to print out the token. And this is my User's model:
<?php
namespace App\Models;
use Illuminate\Notifications\Notifiable;
//use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Facades\Hash;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
const USER_FIRST_NAME_FIELD = "first_name";
const USER_LAST_NAME_FIELD = "last_name";
const USER_PREFERRED_NAME_FIELD = "preferred_name";
const USER_EMAIL_FIELD = "email";
const USER_EMAIL_VERIFIED_AT_FIELD = "email_verified_at";
const USER_PASSWORD_FIELD = "password";
const USER_REMEMBER_TOKEN_FIELD = "remember_token";
const USER_RECEIVE_NEWSLETTER_FIELD= "receive_newsletter";
const USER_ACTIVE_FIELD = "active";
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
self::USER_FIRST_NAME_FIELD,
self::USER_LAST_NAME_FIELD,
self::USER_PREFERRED_NAME_FIELD,
self::USER_EMAIL_FIELD,
self::USER_PASSWORD_FIELD,
self::USER_RECEIVE_NEWSLETTER_FIELD,
self::USER_ACTIVE_FIELD,
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
self::USER_PASSWORD_FIELD,
self::USER_REMEMBER_TOKEN_FIELD
];
/**
* Automatically creates password hash when password is submitted
*
* #param string $password
* #return void
*/
public function setPasswordAttribute(string $password) : void
{
$this->attributes['password'] = Hash::make($password);
}
}
As you can see I'm using HasApiTokens, Notifiable traits and nonetheless I'm getting an error from my controller saying:
Call to undefined method App\User::createToken()
Passport is installed and configured correctly.
Here's something weird:
When registering an user (I'm using a separate controller and also using a service) a token is created successfully:
Here's my controller:
<?php
namespace App\Http\Controllers\API;
use App\Services\UserService;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Http\Requests\RegisterUserRequest;
class UserController extends Controller
{
private $user;
public function __construct(UserService $user)
{
$this->user = $user;
}
public function store(RegisterUserRequest $request) : JsonResponse
{
// TODO: verify message on error
$user = $this->user->register($request->validated());
$token = $user->createToken('MyApp')->accessToken;
dd($token);
return response()->json(['status' => 201, 'user_id' => $user->id]);
}
}
Here's my service:
<?php
namespace App\Services;
use App\Models\User;
use App\Services\BaseServiceInterface;
class UserService implements BaseServiceInterface
{
public function register(array $formValues) : User
{
// 'terms and conditions' should not be saved into the db, hence it's removed
unset($formValues['terms_conditions']);
return User::create($formValues);
}
}
and here's my model again:
<?php
namespace App\Models;
use Illuminate\Notifications\Notifiable;
//use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Facades\Hash;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
const USER_FIRST_NAME_FIELD = "first_name";
const USER_LAST_NAME_FIELD = "last_name";
const USER_PREFERRED_NAME_FIELD = "preferred_name";
const USER_EMAIL_FIELD = "email";
const USER_EMAIL_VERIFIED_AT_FIELD = "email_verified_at";
const USER_PASSWORD_FIELD = "password";
const USER_REMEMBER_TOKEN_FIELD = "remember_token";
const USER_RECEIVE_NEWSLETTER_FIELD= "receive_newsletter";
const USER_ACTIVE_FIELD = "active";
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
self::USER_FIRST_NAME_FIELD,
self::USER_LAST_NAME_FIELD,
self::USER_PREFERRED_NAME_FIELD,
self::USER_EMAIL_FIELD,
self::USER_PASSWORD_FIELD,
self::USER_RECEIVE_NEWSLETTER_FIELD,
self::USER_ACTIVE_FIELD,
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
self::USER_PASSWORD_FIELD,
self::USER_REMEMBER_TOKEN_FIELD
];
As I told you, when creating a user the token is being generated correctly.
I'd say that Auth::user() is not calling my Model directly, but I don't know for sure that's what is happening.
Any idea why?
Thanks
Since your guard is returning the wrong User model, App\User, you should check your auth configuration, 'config/auth.php'. In the providers array adjust any provider, usually users, that is using the App\User model to App\Models\User instead.
'providers' => [
'users' => [
'driver' => 'eloquent',
// 'model' => App\User::class,
'model' => App\Models\User::class,
],
...
],
in my case, i missed to use Trait HasApiTokens
thats why laravel was unable to create tokens.
just open User.php
afetr name space include
use Laravel\Passport\HasApiTokens;
then inside class
use HasApiTokens
Pls note : I am using laravel 7.
So, this is not the right way to do it but it's working at the moment:
<?php
namespace App\Http\Controllers\API;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\API\BaseController;
class AuthController extends BaseController
{
public function login()
{
if (Auth::attempt(['email' => request('email'), 'password' => request('password')])) {
$authenticated_user = \Auth::user();
$user = User::find($authenticated_user->id);
dd($user->createToken('myApp')->accessToken);
}
dd('here');
}
}
Now I'm seeing the token.
I wanna do it the right way so I still would appreciate if any one could help me.
Thanks
you can let the auth.basic middleware do the authentication for you, by calling it in the construct method:
public function __construct()
{
$this->middleware('auth.basic');
}
Then generate the access token for the currently authenticated user, and return the user information along with the access token:
public function login()
{
$Accesstoken = Auth::user()->createToken('Access Token')->accessToken;
return Response(['User' => Auth::user(), 'Access Token' => $Accesstoken]);
}
Now the Controller will look like this:
<?php
namespace App\Http\Controllers\API;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\API\BaseController;
class AuthController extends BaseController
{
/**
* Instantiate a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth.basic');
}
public function login()
{
$Accesstoken = Auth::user()->createToken('Access Token')->accessToken;
return Response(['User' => Auth::user(), 'Access Token' => $Accesstoken]);
}
}
i have updated laravel 6 to 8 & i am using sanctum for API auth.
This works for me when i want to get token for API auth.
in User model
use Laravel\Sanctum\HasApiTokens;
and use the traits in function
use HasApiTokens
Model/User.php
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Hash;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var string[]
*/
protected $fillable = [
'name',
'email',
'password',
'status'
];
/**
* The attributes that should be hidden for serialization.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function setPasswordAttribute($input)
{
if ($input) {
$this->attributes['password'] = app('hash')->needsRehash($input) ? Hash::make($input) : $input;
}
}
public function roles()
{
return $this->belongsToMany(Role::class);
}
public function scopeActive($query){
return $query->where('status', 'ACTIVE');
}
}
I have been trying to figure out why is this happening ! I have used the laravel's built in authentication method ,my laravel version is 5.7 and DB is Mysql.The problem is that when I try to login , there is no reaction performed by the server , otherwise , the signup procedure works correctly .I have to mention that when I use these codes with another database built with migrations, everything goes well . Here is my model :
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
protected $table = 'person';
use Notifiable;
protected $guarded= [];
}
Here is my login controller :
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = '/';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
public function username()
{
return 'username';
}
}
routers
<?php
Auth::routes();
Route::get('/', 'HomeController#index')->name('indexPage');
Route::get('/contact-us', 'ContactUsController#index')->name('contactPage');
Route::get('/about-us', function(){return view('pages.AboutUs');})->name('aboutPage');
Route::resource('/brands' , 'brandController');
I need to display my users table data in the index.blade.php file, but when I visit the index view it displays an empty page, it does not display the variables data, which I need. (No errors are displayed.)
index.blade.php
#if(isset($users))
#foreach($users as $use)
<h1>{{$use->username}}</h1>
#endforeach
#endif
UsersController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Auth;
use App\User;
use App\Http\Requests;
class UserController extends Controller
{
public function index()
{
$users = User::userr()->get();
// $users = User::all();
return view('users.index')->withUser($users);
//dd($users);
}
}
User.php Model
<?php
namespace App;
use Auth;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'username', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function getAvatarUrl()
{
return "http://www.gravatar.com/avatar/" . md5(strtolower(trim($this->email))) . "?d=mm&s=40";
}
public function scopeUserr($query)
{
return $query->where('username',Auth::user()->id);
}
}
Can You give me some solutions?
May be you have to check if the data passed to your blade,
and try to use
$model = App\Flight::findOrFail(1);
return view('page',compact('var'));
check this
http://www.snippetcase.com/snippet/27/Bind+and+Display+data+in+blade+page+for+laravel