I am trying to implement password reset feature in Lumen but could not succeed.
Lumen has access to things like Laravel's PasswordBroker and PasswordManager but I am not able to use this and succeed. Is there any solution for this.
I literally just figured this out last night and wrote a blog about it:
http://www.imjohnbon.com/password-resets-in-lumen/
Hopefully it can at least get you on the right track.
Ok, so I just got this working myself, with Lumen 5.6. (I've upgraded to 5.8, still works, no changes made).
These are the changes I had to make to my code. I had to tweak a few things to suit my system, but this might help someone else.
Routes
I wanted two routes.
Send reset password email
GET auth/resetpassword?email=fred#example.com
Reset Password
PUT auth/resetpassword?token=281...b&username=fred&password=banana&password_confirmation=banana
Composer
To send the user an email, the following Laravel packages are needed:
composer require illuminate/mail "^5.6"
composer require illuminate/notifications "^5.6"
Config files
Some extra config file are needed:
config/auth.php
config/mail.php
I just copied these over from Laravel 5.6, no changes made. I also added the mail variables into my .env file.
bootstrap/app.php
These new files need to be registered in the app:
$app->configure('auth');
$app->configure('mail');
$app->register(Illuminate\Notifications\NotificationServiceProvider::class);
$app->register(\Illuminate\Mail\MailServiceProvider::class);
$app->alias('mailer', \Illuminate\Contracts\Mail\Mailer::class);
$app->withFacades();
Database
I used the default Laravel password_resets table:
Schema::create('password_resets', function (Blueprint $table) {
$table->string('email')->index();
$table->string('token');
$table->timestamp('created_at')->nullable();
});
Now the real changes to the code.
Based on the code from Illuminate\Foundation\Auth\SendsPasswordResetEmails and Illuminate\Foundation\Auth\ResetsPasswords.
AuthController
use Illuminate\Auth\Passwords\PasswordBrokerManager;
use Illuminate\Support\Facades\Password;
use Laravel\Lumen\Routing\Controller;
use Illuminate\Http\Request;
class AuthController extends Controller
{
// 1. Send reset password email
public function generateResetToken(Request $request)
{
// Check email address is valid
$this->validate($request, ['email' => 'required|email']);
// Send password reset to the user with this email address
$response = $this->broker()->sendResetLink(
$request->only('email')
);
return $response == Password::RESET_LINK_SENT
? response()->json(true)
: response()->json(false);
}
// 2. Reset Password
public function resetPassword(Request $request)
{
// Check input is valid
$rules = [
'token' => 'required',
'username' => 'required|string',
'password' => 'required|confirmed|min:6',
];
$this->validate($request, $rules);
// Reset the password
$response = $this->broker()->reset(
$this->credentials($request),
function ($user, $password) {
$user->password = app('hash')->make($password);
$user->save();
}
);
return $response == Password::PASSWORD_RESET
? response()->json(true)
: response()->json(false);
}
/**
* Get the password reset credentials from the request.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
protected function credentials(Request $request)
{
return $request->only('username', 'password', 'password_confirmation', 'token');
}
/**
* Get the broker to be used during password reset.
*
* #return \Illuminate\Contracts\Auth\PasswordBroker
*/
public function broker()
{
$passwordBrokerManager = new PasswordBrokerManager(app());
return $passwordBrokerManager->broker();
}
}
User model
use Illuminate\Auth\Passwords\CanResetPassword as CanResetPasswordTrait;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordInterface;
use Illuminate\Notifications\Notifiable;
class User extends Model implements CanResetPasswordInterface
{
use CanResetPasswordTrait;
use Notifiable;
...
}
Related
I'm working on a project where user and admin are two different login. I want to redirect user and admin to their respective dashboard pages.
I'm not getting how to do this. In database, I created roles column (1 for admin, 2 for user).
I'm not getting how to set send to a different dashboard.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Validator,Redirect,Response;
Use App\User;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Session;
use Socialite;
class AuthController extends Controller
{
public function index()
{
return view('login');
}
public function registration()
{
return view('registration');
}
public function postLogin(Request $request)
{
request()->validate([
'email' => 'required',
'password' => 'required',
]);
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
// Authentication passed...
return redirect()->intended('dashboard');
// return redirect($this->redirectPath());
}
return Redirect::to("login")->withSuccess('Oppes! You have entered invalid credentials');
}
}
Currently on successful login going only same dashboard. I want to change that and send redirection according to roles.
I have created middleware also, but not getting what exact need to do.
<?php
namespace App\Http\Middleware;
use Closure;
Use App\User;
class RoleMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if ($this->auth->check()) {
$auth = Auth::user()->roles()->first();
switch ($auth->role) {
case 'admin':
return redirect()->route('admin');
break;
case 'user':
return redirect()->route('user');
break;
default:
return redirect()->route('login');
break;
}
}
return $next($request);
}
}
and routing will be following
Route::get('login', 'AuthController#index');
Route::post('post-login', 'AuthController#postLogin');
First of all, you don't need to create a middleware for redirecting users based on their role.
Just check the role of user after successful login attempt and do your redirect.
public function postLogin(Request $request)
{
$request->validate([
'email' => 'required',
'password' => 'required',
]);
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
// Authentication passed...
// Set redirect route/path based on user role.
$to = $request->user()->role->name === 'admin' ? 'admin' : 'user';
// Redirect user to a named route.
return redirect()->route($to); // or return redirect($to);
}
return Redirect::to('login')->withSuccess('Oops! You have entered invalid credentials.');
}
You can Manage different different dashboards for User and Admin URLs Easily using Gates method also in Laravel.
refer and Try to understand this Example,
I am using laravel 6.12 using the Authentication artisan command
php artisan ui vue --auth
I have been following https://laraveldaily.com/auth-login-how-to-check-more-than-just-emailpassword/ website . I would like to know the steps needed to authenticate with a triage i.e company, email address and password.
I am receiving a duplicate when I add company name, it thinks this is the email address. Where do you change this? And I am recieving the following error.
BadMethodCallException
Method App\Http\Controllers\Auth\LoginController::company does not exist.
$credentials = $request->only($this->username(), 'password');
$credentials = array_add($credentials, 'company');
I need to Verify the Company name as part of the authentication process. with email, password & Company. Does anyone know how to authenticate using three authentication credentials?
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}
'''
Note: The tutorial you linked shows a bad way of logging in a User using a raw SQL query!. Please use a more standard way.
To login a user using multiple properties do something like this in your Controller method:
public function login(Request $request)
{
//... request validation logic
//take only what is needed to verify login
$credentials = request(['company', 'email', 'password']);
//verify login
if (!Auth::attempt($credentials)) {
return response()->json([
'message' => 'Invalid password'
], 401);
}
//Login user, as you're using Vue I assume you use either JWT or Passport
$user = $request->user();
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
$token->save();
return response()->json([
'access_token' => $tokenResult->accessToken,
'token_type' => 'Bearer',
]);
}
I want to log all URL's that user visited. But there's not the url i want to logged from my code. Here are the code that im done, please give me some advise. Thanks and appreciate.
Web Routes
Route::get('/{url}', 'LogController#myTestAddToLog')->where('url', '[\w\d\-]+(.*)');
Log Controller
public function myTestAddToLog()
{
\LogActivity::addToLog('My Testing Add To Log.');
}
App/Helpers LogActivity
public static function addToLog($subject)
{
$log = [];
$log['url'] = Request::fullUrl();
$log['ip'] = Request::ip();
$log['user_id'] = auth()->check() ? auth()->user()->id : 1;
LogActivityModel::create($log);
}
You need to create a middleware.
php artisan make:middleware AddToLog
And then, put your code inside the middleware.
<?php
namespace App\Http\Middleware;
use Closure;
use App\LogActivityModel;
class AddToLog
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$response = $next($request);
if(auth()->user()) {
LogActivityModel::create([
'url' => request()->fullUrl(),
'ip' => request()->ip(),
'user_id' => auth()->id(),
]);
}
return $response;
}
}
Then, inside app/Http/kernel.php, add your middleware to $middleware. This would allow any URL called would trigger this code.
protected $middleware = [
...
\App\Http\Middleware\AddToLog::class,
];
For those who still has the issue I had modified a bit the answer provided by #Adlan and based on the comments of his answer. Since you will be logging the activities after the request has been performed, the accepted answer needs to be modified. Following is the modified code.
public function handle($request, Closure $next)
{
$response = $next($request);
if(auth()->user()) {
Activity::create([
'url' => request()->fullUrl(),
'ip_address' => request()->ip(),
'user_id' => auth()->id(),
]);
}
return $response;
}
First, the response for the next request is saved. Then user authentication is checked and finally, the response is returned.
Reference : https://laravel.com/docs/5.8/middleware
https://stackoverflow.com/a/59816949/7070809
Please use the below code to log all url that user has visited
Log::info(url()->full()); // For just loggin
And for storing user log create table store the url with timestamp and IP
I made a route in the api file that allow everybody to create users :
Route::post('users', 'UserController#addUser');
When I called it in postman without using request validation it works. But when I created my request file and use it, Laravel return a NotFoundHttpException.
Here's my request file :
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UserAddRequest 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 [
'user_id' => 'required|numeric',
'name' => 'required|string',
'email' => 'required|string',
'password' => 'required|string'
];
}
}
public function addUser(UserAddRequest $request){
$user = new User;
$user->instance_user_id = $request->input('user_id');
$user->name = $request->input('name');
$user->email = $request->input('email');
$user->password = $request->input('password');
$user->save();
}
There is no form because it needs to be send directly to the server with post method. I declared my route in routes/api.php and I call it with the url /api/users The api in that case doesn't need to check credentials.
I solved my problem :
The NotFoundHttpException was raised because I didn't send my parametters correctly and Laravel doesn't where to redirect me back. When I send directly the request to the server there is no url declared for where I'm coming.
This question already has answers here:
Login only if user is active using Laravel
(23 answers)
Closed 2 years ago.
I am new to Laravel and I have done a system with users. Authenticate users is done by "php artisan make:auth", I have a column in users table called activated; when activated = 0, I don't want a user to log in. A little help please? Sorry if this clue has been boring.
You will want to handle this as either using the AuthenticatesUsers trait or manually part of your AuthController by checking the response from your login form and returning an appropriate response:
<?php
namespace App\Http\Controllers;
use App;
use Illuminate\Auth\AuthManager;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
/**
* Class AuthController
* #package Speechlink\Http\Controllers\Auth
*/
class AuthController extends Controller
{
use AuthenticatesUsers;
/**
* Create a new authentication controller instance.
* #param AuthManager $auth
*/
public function __construct(AuthManager $auth)
{
$this->auth = $auth;
}
/**
* Deal with the login attempt (overrides the trait's postLogin method)
*
* #param Request $request
* #return $this|\Illuminate\Http\RedirectResponse
*/
public function postLogin(Request $request)
{
$this->validate($request, [
'username' => 'required',
'password' => 'required',
]);
$credentials = $request->only('username', 'password');
if ($this->auth->attempt($credentials)) {
// We authenticated so continue
return redirect('path/to/logged_in');
} else {
// We failed authentication so redirect somewhere else
return redirect('path/to/disabled_user');
}
}
}
i find out myself, i just add this to myLoginController.php
protected function credentials(Request $request)
{
$credentials = $request->only($this->username(), 'password');
$credentials['activated'] = 1;
return $credentials;
}