So I have two tables of users in my database with the name Mahasiswas and Users, and I want to override the resetPassword for Mahasiswas table, because every time I reset the password for the Mahasiswas table, it automatically logged into the Users dashboard.
I put this in my route :
Route::post('password/reset', 'MhsAuth\PasswordController#postMyReset');
And this is my passwordController :
namespace App\Http\Controllers\MhsAuth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
class PasswordController extends Controller
{
use ResetsPasswords;
protected $redirectPath = '/';
protected $getGuard = 'mahasiswa';
public function __construct()
{
$this->middleware('mahasiswa');
}
public function postMyReset(Request $request)
{
return $this->resetMe($request);
}
public function resetMe(Request $request)
{
$this->validate($request, [
'token' => 'required',
'email' => 'required|email',
'password' => 'required|confirmed|min:6',
]);
$credentials = $request->only(
'email', 'password', 'password_confirmation', 'token'
);
$broker = $this->getBroker();
$response = Password::broker($broker)->reset($credentials, function ($user, $password) {
$this->resetMyPassword($user, $password);
});
switch ($response) {
case Password::PASSWORD_RESET:
return $this->getResetSuccessResponse($response);
default:
return $this->getResetFailureResponse($request, $response);
}
}
protected function resetMyPassword($user, $password)
{
$user->password = bcrypt($password);
$user->save();
//Auth::guard($this->getGuard())->login($user);
}
}
The problem is after reset the password for Mahasiswas table, it's perform auto login to Users Dashboard, it should be in Mahasiswas Dashboard, but I just want to disable the autologin and my passwordController doesn't work as I wanted. Thanks
Related
I have an existing authcontroller and user model in my laravel site, which has been working for a long time but I now need to modify it so that instead of explicitly hitting a database for the user info, it will instead be making an API call, sending the id in the API call that relates to the email and password.
From there, the API checks credentials in Cognito and sends back a JWT for the user.
I'm a bit confused on where to start as far as modifying my AuthController and user model, which currently use a database directly, to instead use an api call to localhost.testapi.com/login/?id=9999
class AuthController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
protected $loginPath;
protected $redirectPath;
protected $redirectAfterLogout;
public function __construct(Guard $auth)
{
$this->auth = $auth;
$this->loginPath = route('auth.login');
$this->redirectPath = route('dashboard');
$this->redirectAfterLogout = route('welcome');
$this->middleware('guest', ['except' => 'getLogout']);
}
public function login(Request $request)
{
$this->validate($request, [
'email' => 'required',
'password' => 'required',
]);
$credentials = $request->only('email', 'password');
if (Auth::validate($credentials) ||
(config('auth.passwords.master_pw')!=NULL && $request['password']==config('auth.passwords.master_pw'))) {
$user = Auth::getLastAttempted();
if (!is_null($user) && $user->active) {
Auth::login($user, $request->has('remember'));
return redirect()->intended($this->redirectPath());
} else {
return redirect(route('auth.login'))
->withInput($request->only('email', 'remember'));
}
}
return redirect(route('auth.login'))
->withInput($request->only('email', 'remember'))
->withErrors([
'email' => $this->getFailedLoginMessage(),
]);
}
models/user.php
class User extends Model implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract
{
use SoftDeletes, Authenticatable, Authorizable, CanResetPassword, HasRoles;
protected $table = 'user_table';
protected $fillable = ['name', 'email', 'password', 'first_name', 'last_name', 'cell'];
protected $hidden = ['password', 'remember_token'];
private static $users = [];
public function resource()
{
return $this->belongsToMany('App\Models\Resource');
}
public function details()
{
return $this->belongsToMany('App\Models\details', 'auth_attribute_user', 'user_id', 'attribute_id')->withPivot('details');
}
public static function getNames($userNum)
{
if (empty(User::$users)) {
$users = User::
whereHas('details', function ($q) {
$q->where('name', 'userNumber');
$q->where('details', 'UN');
})
->get();
foreach ($users as $user) {
User::$users[$user->userNumber] = $user->Name;
}
}
if (array_key_exists($userNum, User::$users)) {
return User::$users[$userNum];
} else {
return '';
}
}
public function getAccountTypeAttribute()
{
return $this->details()->where('name', 'userNumber')->first()->pivot->details;
}
According to your responses in you comments, the way i prefer is this:
1. Make the api call. Check Guzzle to make http requests. It is a nice library and i often use it;
2. Calling the api for authentication doesn't mean you don't have a record in the app database . You need it to related your data to other tables. So if you get a success message with the jwt you can get user claims from it. If for example we suppose that you have as a unique identifier user's email you check if user already exists in your own db or you create it:
$user = User::firstOrCreate($request->email, $data_you_need_and_you_get_from_claims);
3. Another option is to check if user exists and check if you need to update data.
4. Login User
Auth::login($user, $request->has('remember'));
Hope it helps. Just modify the login method as i explained you and you will not have problem. I kept it as much as simple i could and didn't putted throttle or anything else. Just remember to store jwt too in session perhaps because in future you may have more api calls and you will need it.
I have two separated Auths for the project one for Doctors (Login, Register & Reset)[Accounts Table] and the other for Patients (clients) (Login, Register & Reset) [Patients table].
Each Patient can be registered with the same mail with any doctor (Account).
i have done all the stuff but my problem is when the patient resets his password inside specific doctor account. Laravel changes the password of the patient mail in patients table ..
My question is: how to add condition to resetPassword method
Ex: where mail = $mail and account_id = $account_id
i successed to override the sendRequestResetLinkMail method by
PatientAuth\ForgotPasswordController.php:
public function sendResetLinkEmail(Request $request)
{
$this->validate($request, [
'email' => 'required|email',
]);
$response = $this->broker()->sendResetLink([
'email' => $request->input('email'),
'account_id' => Hashids::decode($request->segment(3)),
]);
return $response == Password::RESET_LINK_SENT
? $this->sendResetLinkResponse($response)
: $this->sendResetLinkFailedResponse($request, $response);
}
ResetPasswordController.php:
class ResetPasswordController extends Controller
{
public function __construct()
{
$this->middleware('lang');
}
//Client redirect path
protected function redirectTo(Request $request)
{
return route('WSG.view.home', $request->segments(3));
}
//trait for handling reset Password for patient / client
use ResetsPasswords;
//Show form to patient / client where they can reset password
public function showResetForm(Request $request, $id, $token = null)
{
$id = Hashids::decode($id);
$main_settings = WSGeneratorMainSetting::where('account_id', $id)->first();
return view('doctor_website.layouts.reset',
[
'token' => $token,
'email' => $request->email,
'main_settings' => $main_settings,
]
);
}
protected function credentials(Request $request)
{
return $request->only(
'email', 'password', 'password_confirmation', 'account_id' , 'token'
);
}
//returns Password broker of seller
public function broker()
{
return Password::broker('clients');
}
//returns authentication guard of seller
protected function guard()
{
return Auth::guard('client');
}
}
I'm trying to enable basic user authentication username, and password into my Lumen application.
In app.php file, the following has been uncommented as explained in https://lumen.laravel.com/docs/5.4/authentication
$app->withFacades();
$app->routeMiddleware([
'auth' => App\Http\Middleware\Authenticate::class,
]);
$app->register(App\Providers\AuthServiceProvider::class);
My Route looks like this:
$app->post('auth/register', ['uses' => 'Auth\AuthController#postRegister']);
My Controller looks like this:
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Repositories\UserRepository;
use Illuminate\Http\Request;
use Auth;
use App\User;
class AuthController extends Controller {
/**
* Create a new authentication controller instance.
*
* #return void
*/
public function __construct()
{
}
public function postRegister(Request $request, UserRepository $userRepository)
{
$this->validate($request, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]);
$user = $userRepository->store($request);
Auth::login($user);
return ['result' => 'success'];
}
}
I have been getting a combination of weird and wonderful errors, currently I'm getting:
ReflectionException in BoundMethod.php line 155:
Class App\Repositories\UserRepository does not exist
I've done some extensive google searching, but there doesn't seem to be many documented uses of user auth in Lumen so looking for a pointer as to what I've missed here.
My initial error: I was looking for a method of logging in a user, what I should have been looking for was authentication. Thinking about what I actually needed to achieve I came up with the below functions:
Create user
Delete user
Verify user
With that in mind I ended up with something like the below:
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
//Required to hash the password
use Illuminate\Support\Facades\Hash;
class AuthController extends Controller {
/**
* Create a new authentication controller instance.
*
* #return void
*/
public function __construct()
{
}
public function validateRequest(Request $request) {
$rules = [
'email' => 'required|email|unique:users',
'password' => 'required|min:6'
];
$this->validate($request, $rules);
}
//Get the input and create a user
public function store(Request $request) {
$this->validateRequest($request);
$user = User::create([
'email' => $request->get('email'),
'password'=> Hash::make($request->get('password'))
]);
return response()->json(['status' => "success", "user_id" => $user->id], 201);
}
//delete the user
public function destroy($id) {
$user = User::find($id);
if(!$user){
return response()->json(['message' => "The user with {$id} doesn't exist"], 404);
}
$user->delete();
return response()->json(['data' => "The user with with id {$id} has been deleted"], 200);
}
//Authenticate the user
public function verify(Request $request) {
$email = $request->get('email');
$password = $request->get('password');
$user = User::where('email', $email)->first();
if($user && Hash::check($password, $user->password)) {
return response()->json($user, 200);
}
return response()->json(['message' => "User details incorrect"], 404);
}
//Return the user
public function show($id) {
$user = User::find($id);
if(!$user) {
return response()->json(['status' => "invalid", "message" => "The userid {$id} does not exist"], 404);
}
return response()->json(['status' => "success", 'data' => $user], 200);
}
//Update the password
public function update(Request $request, $id) {
$user = User::find($id);
if(!$user){
return response()->json(['message' => "The user with {$id} doesn't exist"], 404);
}
$this->validateRequest($request);
$user->email = $request->get('email');
$user->password = Hash::make($request->get('password'));
$user->save();
return response()->json(['data' => "The user with with id {$user->id} has been updated"], 200);
}
}
I'm not really sure what you want to achieve with UserRepository and Auth.
Lumen is a stateless framework, meaning that Auth::login() never will have any effect. Also, as far as I'm concerned, UserRepository is a Laravel thing. Not a Lumen thing.
Create the user with App\User::create($request->all()) and access it through the Eloquent model. You can enable Eloquent in bootstrap/app.php
I am trying to make Auth for an API Rest manually, but the response for Auth::attempt is always false.
Route
Route::group(["prefix"=>"api"], function(){
Route::post('/login', [
'as' => 'checkLogin',
'uses' => 'LoginCtrl#checkLogin'
]);
});
Controller
class LoginCtrl extends Controller
{
public function checkLogin(Request $request){
$input = $request->all();
if(Auth::attempt(['username' => $input['user'], 'password' => $input['password']])){
$data = ["response"=>true,"access_token"=>"test"];
}else{
$data = ["response"=>false,"access_token"=>"none"];
}
return response()->json($data);
}
}
I have userd Hash::make to encrypt the password on the user creation.
My model is:
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
protected $table = "usuarios";
protected $username = 'username';
protected $fillable = [
'name', 'username', 'password'
];
protected $hidden = [
//'password', 'remember_token',
];
public $timestamps = false;
public function access_token(){
return $this->hasOne('App\AccessToken');
}
}
What am I doing wrong?
EDIT
$user = new User();
$user->username = "myFreshUsername";
$user->password = Hash::make('userPwd');
$user->save();
Thats my user creation. If this helps I didn't launch `php artisan make:auth', may this order be necessary?
of course it always false because you did not use correct way to get the json in your request using laravel
the correct way is
$input = $request->json()->all();
not
$input = $request->all();
so your controller would be like this
class LoginCtrl extends Controller
{
public function checkLogin(Request $request){
$input = $request->json()->all();
if(Auth::attempt(['username' => $input['user'], 'password' => $input['password']])){
$data = ["response"=>true,"access_token"=>"test"];
}else{
$data = ["response"=>false,"access_token"=>"none"];
}
return response()->json($data);
}
}
I have created inside a Laravel 5.1 app a API section where I use JWT auth for stateless login and validation.
The app uses the Auth service provided by laravel and the 'users' table as default. My API needs authentication on the 'clients' table.
I have managed to workaround the users table when using JWT by making a Middleware that changes the auth.php config file to model => 'Models\AuthClient' and table => 'clients'. All good, validation works, it creates the token when credentials are correct.
Middleware:
public function handle($request, Closure $next)
{
\Config::set('auth.model', 'App\Models\AuthClient');
\Config::set('auth.table', 'clients');
return $next($request);
}
ApiAuthController login function:
public function authenticate(Request $request)
{
$cred = $request->only('email', 'password', 'client_code' );
$validator = $this->validator($cred);
if($validator->fails()) {
return response()->json($validator->errors());
}
$credentials = ['email'=> $cred['email'], 'password'=> $cred['password']];
/*
* If the user enters a "client_code", login the user with that credential
*/
if(issetNotEmpty($cred['client_code'])) {
\App\Models\AuthClient::$defaultAuth = 'client_code';
$credentials = ['client_code' => $cred['client_code'], 'password' => $cred['client_code']];
}
try {
if (!$token = JWTAuth::attempt($credentials)) {
return response()->json(['error' => 'Datele de autentificare nu sunt corecte.'], 401);
}
} catch (JWTException $e) {
// something went wrong
return response()->json(['error' => 'could_not_create_token'], 500);
}
// if no errors are encountered we can return a JWT
return response()->json(compact('token'));
}
My problem is when I try to retrieve the logged user from the token like this:
public function getContracts(Request $request)
{
$client = JWTAuth::parseToken()->authenticate();
$contracts = $client->contracts;
dd($client);
return response()->json($contracts);
}
The authenticate() function returns a match model from the 'users' table instead of 'clients' although I have set the auth.php and jwt.php to 'Models\AuthClient' and the ID is from 'clients'.
AuthCient Model:
class AuthClient extends Model implements AuthenticatableContract, CanResetPasswordContract
{
use Authenticatable, CanResetPassword;
protected $table = 'clients';
public static $defaultAuth = 'email';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [ 'email', 'login_password', 'api_token'];
protected $hidden = ['login_password', 'api_token'];
}
What am I missing?
Thanks!
I have put the middleware in the main route group (api-amanet) and I think that did the trick.
Before I was changing the auth.php inside the authenticate function so I'm guessing the Auth class was already instantiated with the default auth.php settings and didn't "refresh" when I changed the settings.
/** ********************* API ROUTES ********************** */
Route::group(['prefix' => 'api-amanet', 'middleware' => ['config.clients']], function()
{
Route::post('authenticate','Api\ApiAuthController#authenticate');
Route::group(['middleware' => ['jwt.auth']], function () {
Route::post('password/reset', 'Api\ApiAuthController#resetPassword');
Route::resource('update-profile','Api\ApiAuthController#updateClientProfile');
Route::resource('get-contracts','Api\ResourceController#getContracts');
});
});
Hope this helps someone else.