I'm doing authorization using laravel:sanctum for the API. But, when calling the logout() method, I get the following error: Call to a member function tokens() on null. Please help me get rid of this error
AuthController
public function auth(UserLoginRequest $request){
$user = User::query()->where('login', $request->get('login'))->first();
if (!$user || !Hash::check($request->get('password'), $user->password)) {
return response()->json(['message'=>'Попытка входа не удалась'], 400);
}
$token = $user->createToken('api_token')->plainTextToken;
$user->api_token = $token;
$user->save();
return response()->json(['message'=>$user->api_token], 200);
}
public function logout(Request $request) {
$request->user()->tokens()->delete();
return response()->json(['message' => 'Вы вышли из системы'], 200);
}
api.php
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::middleware('auth:sanctum')->get('user', function (UserLoginRequest $request) {
return response()->json(['login' => $request->user()->login]);
});
Route::post('auth', [AuthController::class, 'auth']);
Route::post('authStore', [AuthController::class, 'store']);
Route::get('authLogout', [AuthController::class, 'logout'])->middleware('auth:sanctum');
Route::get('application/{id}', [ApplicationController::class, 'showById']);
Route::get('application', [ApplicationController::class, 'show']);
Route::post('applicationStore', [ApplicationController::class, 'store']);
Route::post('applicationDelete', [ApplicationController::class, 'delete']);
Route::post('userDelete/{user}', [UserController::class, 'delete']);
Route::post('userStore', [UserController::class, 'store']);
Route::post('review', [ReviewController::class, 'show']);
Route::post('reviewCreate', [ReviewController::class, 'create']);
solved this by adding my logout Route inside :-
Route::group(['middleware' => ['auth:sanctum']], function () {
// logout route api code here
}
Use auth('sanctum') instead auth() because of you used to sanctum auth
It should be:
auth('sanctum')->user()->tokens()->delete();
The code should be like following
public function logout(Request $request) {
if ($request->user()) {
$request->user()->tokens()->delete();
}
return response()->json(['message' => 'Вы вышли из системы'], 200);
}
use currentAccessToken() instead of tokens().
Related
I'm using Laravel Breeze + Inertia (React) and want to implement custom auth.
I'm having infinite redirection (ERR_TOO_MANY_REDIRECTS) when visiting /dashboard on this middleware.
Route::get('register', [RegisteredUserController::class, 'create'])
->name('register');
Route::post('register', [RegisteredUserController::class, 'store']);
Route::get('login', [AuthenticatedSessionController::class, 'create'])
->name('login');
Route::post('login', [AuthenticatedSessionController::class, 'store']);
Route::middleware(['custom_auth'])->group(function () {
Route::get('/dashboard', function () {
return Inertia::render('Dashboard');
})->name('dashboard');
});
class CustomAuthMiddleware
{
public function handle(Request $request, Closure $next)
{
if (session()->has('user_data')) {
return redirect(RouteServiceProvider::HOME);
}
return $next($request);
}
}
This works:
namespace App\Http\Middleware;
class RedirectIfAuthenticated
{
public function handle(Request $request, Closure $next, ...$guards)
{
if (session()->has('user_data')) {
return redirect()->route('users.index');
}
return $next($request);
}
}
namespace App\Http\Middleware;
class CustomAuthMiddleware
{
public function handle(Request $request, Closure $next)
{
if (session()->has('user_data')) {
return $next($request);
}
return redirect('login');
}
}
Route::middleware('guest')->group(function () {
Route::get('register', [AuthController::class, 'register'])
->name('register');
Route::post('register', [AuthController::class, 'registerPost']);
Route::get('login', [AuthController::class, 'login'])
->name('login');
Route::post('login', [AuthController::class, 'loginPost']);
});
Route::middleware('custom_auth')->group(function () {
Route::get('/', function () { return redirect()->route('users.index'); });
Route::resource('users', UserController::class);
});
Im trying to use middleware to filter users who hasnt logged in. Somehow users who has logged out still can get inside the routes that are protected by the middleware. I dont know which is the problem here. Here are the files
my route
Route::view("/",'loginmhs');
Route::get('/loginmhs', function () {
return view('loginmhs');
});
Route::post("mhslogin",[LoginController::class,'mhslogin']);
Route::get('/logout',[LoginController::class,'logout']);
Route::group(['middleware'=>['protectedPage']], function(){
Route::get('/dashboard', function () {
return view('dashboardmhs');
});
Route::get('/profil', function () {
return view('profil');
});
});
LoginController
public function mhslogin(Request $req){
$datareq = $req->input();
$data = DB::table('tbl_mahasiswa')
->join('tbl_prodi', 'tbl_mahasiswa.id_prodi', '=', 'tbl_prodi.id_prodi')
->where('nim', $req->nim)->first();
if(!$data){
return redirect('/loginmhs')->with('alert','NIM tidak ditemukan...Cek kembali NIM anda.')->with('cek','dikirim');
}
if($req->password == $data->password){
$req->session()->put('nim', $data->nim);
$req->session()->put('nama', $data->nama);
$req->session()->put('email', $data->email);
$req->session()->put('password', $data->password);
$req->session()->put('stambuk', $data->stambuk);
$req->session()->put('id_prodi', $data->id_prodi);
$req->session()->put('nama_prodi', $data->nama_prodi);
return redirect('/profil');
}
return redirect('/loginmhs')->with('alert','Password anda salah!');
}
public function logout(){
if(session()->has('nim')||session()->has('nip')){
session()->forget('nim');
session()->forget('nama');
session()->forget('email');
session()->forget('password');
session()->forget('stambuk');
session()->forget('id_prodi');
session()->forget('nama_prodi');
session()->save();
}
return redirect('/');
}
Middleware loginSessionCheck
public function handle(Request $request, Closure $next)
{
if(!session()->has('nim')){
return redirect('/')
}
return $next($request);
}
kernel
'protectedPage' => [
\App\Http\Middleware\loginSessionCheck::class,
],
The reason is that for the routes you are trying to protect doesn't have access to session. You must also include web middleware group to the group containing protected routes.
Route::middleware(['web', 'protectedPage'])
->group(function() {
Route::get('/dashboard', function () {
return view('dashboardmhs');
});
Route::get('/profil', function () {
return view('profil');
});
});
I'm new to laravel, I'm building an API and using laravel sanctum to implement authorization. After authorization, I get the user token, but I can't get any other user data so that I can, for example, extract the ID of the authorized user or substitute it in another table from the database, or use the data of the authorized user in any way. I don't know what exactly I did wrong. Please help me solve this problem. Here is my code:
AuthController:
<?php
namespace App\Http\Controllers;
use App\Http\Requests\UserCreateRequest;
use App\Http\Requests\UserLoginRequest;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Builder;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use phpDocumentor\Reflection\DocBlock\Tags\Uses;
class AuthController extends Controller
{
public function store(UserCreateRequest $request){
$user = new User();
$user->login = $request->get('login');
$user->password = Hash::make($request->get('password'));
$user->email = $request->get('email');
$user->number_phone = $request->get('number_phone');
// $user->role_id = 1;
$user->assignRole('user');
if (!$user->save()) {
return response()->json(['message'=>'Регистрация не удалась']);
}
return response()->json(['message'=>$user->jsonSerialize()]);
}
public function auth(UserLoginRequest $request){
$user = User::query()->where('login', $request->get('login'))->first();
if (!$user || !Hash::check($request->get('password'), $user->password)) {
return response()->json(['message'=>'Попытка входа не удалась'], 400);
}
$token = $user->createToken('api_token')->plainTextToken;
$user->api_token = $token;
$user->save();
return response()->json(['message'=>$user->api_token = $token], 200);
}
public function logout(Request $request) {
$request->user()->currentAccessToken()->delete();
return response()->json(['message' => 'Вы вышли из системы'], 200);
}
}
Api.php:
<?php
use App\Http\Controllers\ApplicationController;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\ReviewController;
use App\Http\Controllers\UserController;
use App\Http\Requests\UserLoginRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
Route::group(['middleware' => ['role:admin']], function () {
Route::get('test', function () {
return view('test');
});
});
Route::post('auth', [AuthController::class, 'auth']);
Route::post('authStore', [AuthController::class, 'store']);
Route::get('authLogout', [AuthController::class, 'logout'])->middleware('auth:sanctum');
Route::get('application/{id}', [ApplicationController::class, 'showById']);
Route::get('application', [ApplicationController::class, 'show']);
Route::post('applicationStore', [ApplicationController::class, 'store']);
Route::post('applicationDelete', [ApplicationController::class, 'delete']);
Route::post('userDelete/{user}', [UserController::class, 'delete']);
Route::post('userStore', [UserController::class, 'store']);
Route::get('review', [ReviewController::class, 'show']);
Route::post('reviewStore', [ReviewController::class, 'store']);
Route::post('review/{id}', [ReviewController::class, 'update']);
UserLoginRequest:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UserLoginRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'login' => 'required|string',
'password' => 'required|string',
];
}
}
Kernel.php:
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
use Illuminate\Support\Facades\Auth;
// Get the currently authenticated user...
$user = Auth::user();
// Get the currently authenticated user name...
$username = Auth::user()->name;
// Get the currently authenticated user's ID...
$id = Auth::id();
in blade.php you can get it like this
{{{ isset(Auth::user()->name) ? Auth::user()->name : Auth::user()->id }}}
I'm new to Laravel. I want to get an authorized user using the Auth::user () facade, in order to extract its ID, in the logout() method this is obtained and the authorized user is returned as an array with its data, but in the store() method Auth:: user () returns null. Tell me, please, what is the problem?
AuthController (here is logout()):
<?php
namespace App\Http\Controllers;
use App\Http\Requests\UserCreateRequest;
use App\Http\Requests\UserLoginRequest;
use Egulias\EmailValidator\Exception\AtextAfterCFWS;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Builder;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use phpDocumentor\Reflection\DocBlock\Tags\Uses;
class AuthController extends Controller
{
public function store(UserCreateRequest $request){
$user = new User();
$user->login = $request->get('login');
$user->password = Hash::make($request->get('password'));
$user->email = $request->get('email');
$user->number_phone = $request->get('number_phone');
$user->assignRole('user');
if (!$user->save()) {
return response()->json(['message'=>'Регистрация не удалась']);
}
return response()->json(['message'=>$user->jsonSerialize()]);
}
public function login(UserLoginRequest $request){
$user = User::query()->where('login', $request->get('login'))->first();
if (!$user || !Hash::check($request->get('password'), $user->password)) {
return response()->json(['message'=>'Попытка входа не удалась'], 400);
}
$token = $user->createToken('api_token')->plainTextToken;
$user->api_token = $token;
$user->save();
$user = Auth::login($user);
return response()->json(['message'=>Auth::user()->api_token], 200);
}
public function logout(Request $request) {
dd(Auth::user());
$request->user()->currentAccessToken()->delete();
return response()->json(['message' => 'Вы вышли из системы'], 200);
}
AuthController (here is store()):
<?php
namespace App\Http\Controllers;
use App\Http\Requests\ApplicationCreateRequest;
use Illuminate\Http\Request;
use App\Models\Application;
use App\Models\Status;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
class ApplicationController extends Controller
{
public function showById($id) {
return response()->json(Application::find($id), 200);
}
public function show() {
return response()->json(Application::all(), 200);
}
public function store(ApplicationCreateRequest $request){
dd(Auth::user());
//$application = new Application();
//dd(Auth::user()->api_token);
//$application->user_id = Auth::id();
//$application->status_id = 1;
//$application->description = $request->get('description');
//
//if (!$application->save()) {
// return response()->json(['message'=>'Заявка не отправлена'], 500);
//}
//
//return response()->json(['message'=>$application->jsonSerialize()]);
}
public function delete(Application $application) {
if ($application->delete()) {
return response()->json('Заявка удалёна', 200);
}
return response()->json(['message' => 'Заявка не удалёна'], 500);
}
// public function updateStatus(Application $application)
// {
// if ($application->status_id)
// }
}
api.php:
<?php
use App\Http\Controllers\ApplicationController;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\ReviewController;
use App\Http\Controllers\AdminController;
use App\Http\Requests\UserLoginRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
Route::group(['middleware' => ['role:admin']], function () {
});
Route::post('login', [AuthController::class, 'login']);
Route::post('authStore', [AuthController::class, 'store']);
Route::get('authLogout', [AuthController::class, 'logout'])->middleware('auth:sanctum');
Route::get('application/{id}', [ApplicationController::class, 'showById']);
Route::get('application', [ApplicationController::class, 'show']);
Route::post('applicationStore', [ApplicationController::class, 'store'])->middleware('auth:sanctum');
Route::post('applicationDelete/{application}', [ApplicationController::class, 'delete'])->middleware('auth:sanctum');
//Route::post('userDelete/{user}', [AdminController::class, 'delete']);
Route::post('userStore', [AdminController::class, 'store']);
Route::get('user', [AdminController::class, 'show']);
Route::get('user/{id}', [AdminController::class, 'showById']);
Route::post('userDelete/{user}', [AdminController::class, 'delete'])->middleware('auth:sanctum');
Route::get('review', [ReviewController::class, 'showReview']);
Route::get('review/{id}', [ReviewController::class, 'showReviewById']);
Route::post('reviewStore', [ReviewController::class, 'store'])->middleware('auth:sanctum');
Route::post('reviewUpdate/{id}', [ReviewController::class, 'updateReview'])->middleware('auth:sanctum');
Route::post('reviewRatingUpdate/{id}', [ReviewController::class, 'updateReviewRating'])->middleware('auth:sanctum');
Route::get('reviewRating', [ReviewController::class, 'showReviewRating'])->middleware('auth:sanctum');
Route::get('reviewRating/{id}', [ReviewController::class, 'showReviewRatingById']);
Route::get('authUser', [AuthController::class, 'user']);
Define middleware in the constructer of your controller and it will do the trick here
public function __construct()
{
$this->middleware('auth:api');
}
Or moved the route into Route::middleware it will work
Route::middleware('auth:api')->group( function () {
Route::post('authStore', [AuthController::class, 'store']);
});
Use
public function __construct()
{
$this->middleware('auth:api', ['except' => ['login', 'register']]);
}
at the start
register method
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required|string|between:2,100',
'email' => 'required|string|email|max:100|unique:users',
'password' => 'required|string|confirmed|min:6',
'mobile' => 'required|min:10',
]);
if ($validator->fails()) {
return response()->json($validator->errors()->toJson(), 400);
}
$user = User::create(array_merge(
$validator->validated(),
[
'password' => bcrypt($request->password),
]
));
return response()->json([
'message' => 'User successfully registered',
'user' => $user
], 201);
}
Don't working authentication. I create authentication manually.
My AdminController:
class AdminController extends Controller
{
public function signin() {
return view('admin.signin');
}
public function index(Request $request) {
dd(Auth::check());
if (Auth::check())
return view('admin.index.index', ['login' => Auth::user()->name]);
else
return redirect()->action('AdminController#signin');
}
public function login() {
$data = Input::all();
if (Auth::attempt(['name' => $data['login'], 'password' => $data['password']])) {
return redirect()->intended('/admin');
} else {
return redirect()->intended('/admin/signin');
}
}
public function logout() {
if (Auth::logout() ) {
return Redirect::to('/admin');
}
}
}
My routes.php file:
//GET
Route::get('/', 'IndexController#index');
Route::get('/admin/signin', 'AdminController#signin');
Route::get('/admin', 'AdminController#index');
Route::get('/admin/logout', 'AdminController#logout');
//POST
Route::post('/admin/auth', 'AdminController#login');
dd(Auth::check()); returned false
What I doing wrong?
In Laravel 5.2 you need to define routes using web middleware to make sessions work, so your routes.php file should look like this:
Route::group(['middleware' => ['web']], function () {
//GET
Route::get('/', 'IndexController#index');
Route::get('/admin/signin', 'AdminController#signin');
Route::get('/admin', 'AdminController#index');
Route::get('/admin/logout', 'AdminController#logout');
//POST
Route::post('/admin/auth', 'AdminController#login');
});