I'm trying to give a condition is user suspend, user should redirect to login page if user in login state.
I have tried to give a check in AppServiceProvider like below
public function boot()
{
if(auth()->user()->is_deleted === true) return redirect('/logout');
}
Problem is in AppServiceProvider I'm not getting any auth information. How I can solve this problem ?
You can do this better with Middlewares,
Create a middleware CheckIfDeleted
php artisan make:middleware CheckDeleted
Open the CheckIfDeleted and update the handle method:
public function handle(Request $request, Closure $next)
{
if(auth()->check() && auth()->user()->is_deleted === true){
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('some error page?');
}
return $next($request);
}
Open the Kernel.php (app/http folder), then add the new middleware in the web section (protected $middlewareGroups):
\App\Http\Middleware\CheckIfDeleted::class,
I also recommend you implement the softDelete of laravel, you can use this guide from stack: Laravel Soft Delete posts
In this case if the user is deleted, they will get an error message, and you will still keep the record of the user :)
Hi everyone on this day I am designing my website and any new user must register on that and I used email to verification from them.
I am using laravel on my website I want to use the real email to send verification code for the new users I don't want a mail-trap service I want the real email. please tell me what I need to complete this job.
Remember that I want to do this when my website on free hosting, not real hosting.
You can implement the email through the event or in the same controller. My solution has been tested on Laravel 5.6. First of all, make the email settings for gmail in the .env file.
MAIL_DRIVER=smtp
MAIL_HOST=smtp.googlemail.com
MAIL_PORT=465
MAIL_USERNAME=real email
MAIL_PASSWORD=real password
MAIL_ENCRYPTION=ssl
Suppose you want the users to have to activate their account after registration. So create a new model:
php artisan make:modal VerifyUser –m
Add this code to created migration:
public function up()
{
Schema::create('verify_users', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->string('token')->index();
$table->timestamps();
});
}
Then add verified field to the users table:
$table->boolean('verified')->default(false);
Then:
php artisan migrate
Add this method to User Model:
class User extends Authenticatable
{
public function verifyUser()
{
return $this->hasOne('App\VerifyUser');
}
}
Add this method to VerifyUser Model:
class VerifyUser extends Model
{
protected $guarded = [];
public function user()
{
return $this->belongsTo('App\User', 'user_id');
}
}
Create a class for email that inherits from Maiable. This file is created in the email folder.
php artisan make:mail VerifyMail
Apply the following changes to VerifyMail class:
namespace App\Mail;
...
class VerifyMail extends Mailable
{
use Queueable, SerializesModels;
public $user;
public function __construct($user)
{
$this->user = $user;
}
public function build()
{
return $this->view('emails.verifyUser');
}
}
Create a folder named emails and make a blade file named verifyUser in it. And Put the following code in it:
<body>
<h2>Welcome to the site {{$user['name']}}</h2>
<br/>
Your registered email-id is {{$user['email']}} , Please click on the below link to verify your email account
<br/>
Verify Email
</body>
Change create method in RegisterController:
use App\Mail\VerifyMail;
use App\VerifyUser;
use Illuminate\Support\Facades\Mail;
use Illuminate\Http\Request;
...
protected function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
$verifyUser = VerifyUser::create([
'user_id' => $user->id,
'token' => sha1(time())
]);
\Mail::to($user->email)->send(new VerifyMail($user));
return $user;
}
With this method, after the user register, a record is added to the user table, but the verified value is currently false or zero. Now to prevent the user login in immediately after registration, add the following method to the RegisterController:
protected function registered(Request $request, $user)
{
$this->guard()->logout();
return redirect('/login')->with('status', 'We sent you an activation code. Check your email and click on the link to verify.');
}
Unverified user should not log in in any way. And you have to override authenticated method to successful user login. So add authenticated method into LoginController:
public function authenticated(Request $request, $user)
{
if (!$user->verified) {
auth()->logout();
return back()->with('warning', 'You need to confirm your account. We have sent you an activation code, please check your email.');
}
return redirect()->intended($this->redirectPath());
}
Add this code to login.blade.php to display the message above:
#if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
#endif
#if (session('warning'))
<div class="alert alert-warning">
{{ session('warning') }}
</div>
#endif
Next, define a route for the link you sent to the user's email:
Route::get('/user/verify/{token}', 'Auth\RegisterController#verifyUser');
Now it's time to activate the user. Therefore, the verified value must be set to true or one. Add the following method to RegisterController:
public function verifyUser($token)
{
$verifyUser = VerifyUser::where('token', $token)->first();
if(isset($verifyUser) ){
$user = $verifyUser->user;
if(!$user->verified) {
$verifyUser->user->verified = 1;
$verifyUser->user->save();
$status = "Your e-mail is verified. You can now login.";
} else {
$status = "Your e-mail is already verified. You can now login.";
}
} else {
return redirect('/login')->with('warning', "Sorry your email cannot be identified.");
}
return redirect('/login')->with('status', $status);
}
Complete.
I want to save the user id,name etc when a successfull login happens.
This is my code,
public function Login(Request $request){
$result1=json_decode(DB::table('tbl_admin_details')
->where('Username',$request->input('username'))
->where('Password',base64_encode($request->input('password')))
->get(),true);
if(count($result1)>0){
return redirect('dashboard');
}else{
return redirect('/');
}
}
when a successfull login happens it will redirect to dashboard, I need to access the user data in that page. how its possible ???
if(count($result1)>0) {
$id= session(['id'=>$result1[0]->id]);
$name= session(['name'=>$result1[0]->name]);
return redirect('dashboard');
}
Then use session()->get('id') and session()->get('name').
in your loginController put method:
protected function authenticated( \Illuminate\Http\Request $request, $user) {
dd(\Auth::user());
}
this method fires up when user is successfully logged in
and gives you logged in user information.
feel free to use it as you want
I want to delete some user, and if that user have an avatar i want to remove the avatar either. so i do like this :
public function destroy($id)
{
$user = User::findOrFail($id);
if ($user && $user->profile->avatar){
Storage::delete($user->profile->avatar);
}
User::destroy($id);
return back();
}
but when i do this it give me an error like this when user doesn't have any record in avatar tables:
"Trying to get property of non-object"
so what make me get this errors and how can i fix it. thanks.
You need to check if user has profile, first.
if ($user && $user->profile && $user->profile->avatar){
Storage::delete($user->profile->avatar);
}
Anyways, doing this at model level will make your controller a little bit cleaner. Example for attaching a listener through the model directly.
class User extends Model
{
protected static function boot()
{
parent::boot();
static::deleting(function ($instance) {
if ($instance->profile && $instance->profile->avatar) {
\Storage::delete($instance->profile->avatar);
}
});
}
}
I'm currently using 2 projects. 1 front end (with laravel backend to communicate with API) and another laravel project (the API).
Now I use Laravel Passport to authenticate users and to make sure every API call is an authorized call.
Now when I want to log out my user, I send a post request to my API (with Bearer token) and try to log him out of the API (and clear session, cookies,...)
Then on the client I also refresh my session so the token is no longer known. Now when I go back to the login page, it automatically logs in my user. (Or my user is just still logged in).
Can someone explain me how to properly log out a user with Laravel passport?
Make sure that in User model, you have this imported
use Laravel\Passport\HasApiTokens;
and you're using the trait HasApiTokens in the User model class using
use HasApiTokens
inside the user class.
Now you create the log out route and in the controller,
do this
$user = Auth::user()->token();
$user->revoke();
return 'logged out'; // modify as per your need
This will log the user out from the current device where he requested to log out. If you want to log out from all the devices where he's logged in. Then do this instead
$tokens = $user->tokens->pluck('id');
Token::whereIn('id', $tokens)
->update(['revoked'=> true]);
RefreshToken::whereIn('access_token_id', $tokens)->update(['revoked' => true]);
Make sure to import these two at the top
use Laravel\Passport\RefreshToken;
use Laravel\Passport\Token;
This will revoke all the access and refresh tokens issued to that user. This will log the user out from everywhere. This really comes into help when the user changes his password using reset password or forget password option and you have to log the user out from everywhere.
You need to delete the token from the database table oauth_access_tokens
you can do that by creating a new model like OauthAccessToken
Run the command php artisan make:model OauthAccessToken to create the model.
Then create a relation between the User model and the new created OauthAccessToken Model , in User.php add :
public function AauthAcessToken(){
return $this->hasMany('\App\OauthAccessToken');
}
in UserController.php , create a new function for logout:
public function logoutApi()
{
if (Auth::check()) {
Auth::user()->AauthAcessToken()->delete();
}
}
In api.php router , create new route :
Route::post('logout','UserController#logoutApi');
Now you can logout by calling posting to URL /api/logout
This is sample code i'm used for log out
public function logout(Request $request)
{
$request->user()->token()->revoke();
return response()->json([
'message' => 'Successfully logged out'
]);
}
Create a route for logout:
$router->group(['middleware' => 'auth:api'], function () use ($router) {
Route::get('me/logout', 'UserController#logout');
});
Create a logout function in userController ( or as mentioned in your route)
public function logout() {
$accessToken = Auth::user()->token();
DB::table('oauth_refresh_tokens')
->where('access_token_id', $accessToken->id)
->update([
'revoked' => true
]);
$accessToken->revoke();
return response()->json(null, 204);
}
I am using Laravel 6.12.0, below function is working for me.
public function logout(Request $request){
$accessToken = Auth::user()->token();
$token= $request->user()->tokens->find($accessToken);
$token->revoke();
$response=array();
$response['status']=1;
$response['statuscode']=200;
$response['msg']="Successfully logout";
return response()->json($response)->header('Content-Type', 'application/json');
}
This is my first post.. and i find a clean solution (Laravel last Version)
/**
* Logout api
*
* #return \Illuminate\Http\Response
*/
public function logout(Request $request)
{
if (Auth::check()) {
$token = Auth::user()->token();
$token->revoke();
return $this->sendResponse(null, 'User is logout');
}
else{
return $this->sendError('Unauthorised.', ['error'=>'Unauthorised'] , Response::HTTP_UNAUTHORIZED);
}
}
Below is the simplest way I found to do it.
1. USE database SESSION INSTEAD OF file SESSION
Official documention
php artisan session:table
php artisan migrate
Replace SESSION_DRIVER=file by SESSION_DRIVER=database in your .env file.
2. DELETE USER SESSION RIGHT AFTER LOGIN
After a user is redirected to your frontend and logs in to finally get a token, you probably call a route in api/routes.php to get the user information, that's where I'm closing the user backend session before sending back user information to the frontend:
Route::middleware('auth:api')->get('/user', function (Request $request) {
// Close user session here
Illuminate\Support\Facades\DB::table('sessions')
->whereUserId($request->user()->id)
->delete();
return $request->user();
});
3. REVOKE TOKENS AT LOGOUT
Then, to "log out" (actually, revoke tokens) the user from the frontend, you just need to call another route to revoke the token and refresh_token:
Route::middleware('auth:api')->post('/logout', function (Request $request) {
// Revoke access token
// => Set oauth_access_tokens.revoked to TRUE (t)
$request->user()->token()->revoke();
// Revoke all of the token's refresh tokens
// => Set oauth_refresh_tokens.revoked to TRUE (t)
$refreshTokenRepository = app('Laravel\Passport\RefreshTokenRepository');
$refreshTokenRepository->revokeRefreshTokensByAccessTokenId($request->user()->token()->id);
return;
});
You may prefer to put these two closures in the UserController.
Hope help someone:
if (Auth::check()) {
$request->user()->tokens->each(function ($token, $key) {
$token->delete();
});
}
Good Luck.
I use this in my project to logout from multiple device.
public function logout(Request $request, $devices = FALSE)
{
$this->logoutMultiple(\Auth::user(), $devices);
return response()->json([], 204);
}
private function logoutMultiple(\App\Models\User $user, $devices = FALSE)
{
$accessTokens = $user->tokens();
if ($devices == 'all') {
} else if ($devices == 'other') {
$accessTokens->where('id', '!=', $user->token()->id);
} else {
$accessTokens->where('id', '=', $user->token()->id);
}
$accessTokens = $accessTokens->get();
foreach ($accessTokens as $accessToken) {
$refreshToken = \DB::table('oauth_refresh_tokens')
->where('access_token_id', $accessToken->id)
->update(['revoked' => TRUE]);
$accessToken->revoke();
}
}
Try this code to help you to logout from passport authentication.
Route::post('/logout', function(){
if (Auth::check()) {
Auth::user()->AauthAcessToken()->delete();
}
return response()->json([
'status' => 1,
'message' => 'User Logout',
], 200);
});
check whether your model contains OauthAccessToken which needs to connect with the database oauth_access_tokens. The access token is stored in the database table oauth_access_tokens. and makes a relation from users to oauth_access_tokens.
public function AauthAcessToken(){
return $this->hasMany(OauthAccessToken::class);
}
You can use following code to remove to token for logged in user.
$request->user()->token()->revoke();
If you want to learn about this in-depth then watch this tutorial:
https://www.youtube.com/watch?v=UKSQdg1uPbQ
public function logout(Request $request)
{
$request->user()->token()->revoke();
if ($request->everywhere) {
foreach ($request->user()->tokens()->whereRevoked(0)->get() as $token) {
$token->revoke();
}
}
return response()->json(['message' => 'success']);
}