I don't know why Auth:attempt alway return false.
Here is my controller:
public function login(Request $request)
{
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:6'
]);
$user = [
'email' => $request['email'],
'password' => bcrypt($request['password']),
];
if (Auth::guard('admin')->attempt($user)) {
return redirect()->intended(route('admin.dashboard'));
}
return back()->withInput($request->only('email', 'remember'));
}
Here is my Model:
use 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 setPasswordAttribute($value) {
$this->attributes['password'] = bcrypt($value);
}
Here is my route:
Route::group(['prefix' => 'admin'], function () {
Route::get('login', 'Admin\LoginController#showLoginForm')->name('admin.login');
Route::post('login', 'Admin\LoginController#login')->name('admin.login.post');
Route::get('logout', 'Admin\LoginController#logout')->name('admin.logout');
Route::group(['middleware' => ['auth:admin']], function () {
Route::get('/', function () {
return view('admin.dashboard.index');
})->name('admin.dashboard');
});
});
In controller i get array from html to send. But when in if (Auth::guard('admin')->attempt($user)) is alway false. I don't know why.
Please help me.
Thank so much.
Related
I am making an authentication api using Laravel passport
when I try to return the access token I get this :
"access_token": {
"name": "authToken",
"abilities": [
"*"
],
"tokenable_id": 60,
"tokenable_type": "App\\Models\\User",
"updated_at": "2022-06-03T17:07:16.000000Z",
"created_at": "2022-06-03T17:07:16.000000Z",
"id": 12
}
},
"message": "data has been retrieved"
}
I don't know where the token is
and this is my login controller
$rules =[
'email' => 'email|required',
'password' => 'required'
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return response()->json(['message' => 'there is been an error', 'error message' => $validator->errors()]);
}
$loginData = $request->input();
if (!auth()->attempt($loginData)) {
return response(['message' => 'Invalid credentials']);
}
$user = $request->user();
$data['user'] = $user;
$data['access_token'] = $user->createToken('authToken')->accessToken;
return response()->json([$data, "message" => "data has been retrieved"]) ;
I think you have implemented all the necessary commands to work with laravel passport.
This makes it possible to take with a refresh token.
Try this:
use Laravel\Passport\Client as OClient;
use GuzzleHttp\Client;
public function login(Request $request){
....
// $laravelPasswordGrantClientId - this is the id of the client whose database you have
$oClient = OClient::find($laravelPasswordGrantClientId);
return response()->json($this->getTokenAndRefreshToken($oClient, request('email'), request('password')),200);
}
public function getTokenAndRefreshToken(OClient $oClient, $email, $password) {
$oClient = OClient::find($laravelPasswordGrantClientId);
$http = new Client;
$response = $http->request('POST', 'http://your.domain.com/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => $oClient->id,
'client_secret' => $oClient->secret,
'username' => $email,
'password' => $password,
'scope' => '*',
],
]);
$result = json_decode((string) $response->getBody(), true);
return $result;
}
app/Models/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 Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* 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',
];
}
make sure you have Laravel\Passport\HasApiTokens; in User.php
I've tried to create an admin module for a schoolproject with laravel.
I copied all the authentication stuff to register a person, but changed everything so it's a a different module. However, I can't seem to fix this problem. It always says that my 'created_at' doesn't have a default value. But it has the timestamp() module so I would think that it doesn't need anything else. Anyone who sees the fault.
My Migration:
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('admins', function (Blueprint $table) {
$table->increments('admin_id');
$table->string('naam');
$table->string('email')->unique;
$table->binary('password');
$table->enum('rol', ['user','admin'])->default('admin');
$table->timestamp('created_at')->nullable();
$table->timestamp('updated_at')->nullable();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('admins');
}
};
My model
class Admin extends Model
{
use HasFactory;
protected $table = 'admins';
protected $primaryKey = 'admin_id';
protected $fillable =
[
'admin_id',
'naam',
'email',
'password',
'rol',
];
public $timestamps = false;
}
My Controller
class RegisteredUserController extends Controller
{
/**
* Display the registration view.
*
* #return \Illuminate\View\View
*/
public function create()
{
return view('auth.register');
}
/**
* Handle an incoming registration request.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\RedirectResponse
*
* #throws \Illuminate\Validation\ValidationException
*/
public function store(Request $request)
{
$request->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'confirmed', 'min:5'],
]);
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
event(new Registered($user));
Auth::login($user);
return redirect(RouteServiceProvider::HOME);
}
public function createAdmin()
{
return view('auth.registeradmin');
}
public function storeAdmin(Request $request)
{
$request->validate([
'naam' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'confirmed', 'min:5'],
]);
$admin = Admin::create([
'naam' => $request->naam,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
event(new Registered($admin));
Auth::login($admin);
return redirect(RouteServiceProvider::HOME);
}
}
I have used JWT in Laravel for user Authentication
Auth Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
use Illuminate\Auth\Events\Verified;
use Validator;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Notification;
class AuthController extends Controller
{
public function __construct() {
$this->middleware('auth:api', ['except' => ['login', 'register']]);
}
/**
* Get a JWT via given credentials.
*
* #return \Illuminate\Http\JsonResponse
*/
public function login(Request $request){
$validator = Validator::make($request->all(), [
'email' => 'required|email',
'password' => 'required|string|min:6',
]);
if ($validator->fails()) {
return response()->json($validator->errors(), 422);
}
if (! $token = auth()->attempt($validator->validated())) {
return response()->json(['status'=>true,'error_message' => 'Invalid Credentials'], 401);
}
return $this->createNewToken($token);
}
/**
* Register a User.
*
* #return \Illuminate\Http\JsonResponse
*/
public function register(Request $request) {
$messages = [
'password.confirmed' => 'Password Confirmation should match the Password',
'password.min' => ' Password should be minimum 6 digits',
];
$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',
],$messages);
if($validator->fails()){
return response()->json($validator->errors(), 422);
}
$user = User::create(array_merge(
$validator->validated(),
['password' => bcrypt($request->password)]
));
return response()->json([
'message' => 'Successfully registered',
], 201);
}
/**
* Log the user out (Invalidate the token).
*
* #return \Illuminate\Http\JsonResponse
*/
public function logout() {
auth()->logout();
return response()->json(['message' => 'User successfully signed out']);
}
/**
* Refresh a token.
*
* #return \Illuminate\Http\JsonResponse
*/
public function refresh() {
return $this->createNewToken(auth()->refresh());
}
/**
* Get the authenticated User.
*
* #return \Illuminate\Http\JsonResponse
*/
public function userProfile() {
return response()->json(auth()->user());
}
/**
* Get the token array structure.
*
* #param string $token
*
* #return \Illuminate\Http\JsonResponse
*/
protected function createNewToken($token){
return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => auth()->factory()->getTTL() * 60,
'user' => auth()->user()
]);
}
}
routes :
Route::group([
'middleware' => ['api'],
'prefix' => 'auth'
], function ($router) {
Route::post('/login', [AuthController::class, 'login']);
Route::post('/register', [AuthController::class, 'register']);
Route::post('/logout', [AuthController::class, 'logout']);
Route::post('/refresh', [AuthController::class, 'refresh']);
Route::get('/user-profile', [AuthController::class, 'userProfile']);
Login and register is working
but when i access user-profile route getting this error :
Symfony\Component\Routing\Exception\RouteNotFoundException: Route
[login] not defined. in file
C:\wamp64\www\project\vendor\laravel\framework\src\Illuminate\Routing\UrlGenerator.php
on line 420
and i cannot get id of user if some user is logged in using : auth()->user()->id
auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
'hash' => false,
],
'admin' => [
'driver' => 'session',
'provider' => 'users',
],
],
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 Tymon\JWTAuth\Contracts\JWTSubject;
class User extends Authenticatable implements JWTSubject
{ #HasFactory,
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
'email',
'password',
'otp',
'user_verification_token',
'verified',
'token',
'email_verified_at'
];
/**
* 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 getJWTIdentifier() {
return $this->getKey();
}
public function getJWTCustomClaims() {
return [];
}
}
Any suggestion is highly appreciated
Thanks
Error message says there is no route that named as 'login'
Route::post('/login', [AuthController::class, 'login'])->name('login');
I am getting an error while trying to Auto Login After successful registration in laravel 6 getting the following error.
Argument 1 passed to Illuminate\Auth\SessionGuard::login() must implement interface Illuminate\Contracts\Auth\Authenticatable, null given, called in
My Registercontroller is
class RegisterController extends Controller
{
use RegistersUsers;
protected $redirectTo = RouteServiceProvider::HOME;
public function __construct()
{
$this->middleware('guest');
// $this->middleware(['auth','verified']);
}
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'min:3'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
protected function create(array $data)
{
$username = slugify($data['name'])."-".mt_rand(10000, 99999);
$user = User::create([
'name' => $data['name'],
'username' => $username,
'email' => $data['email'],
'password' => Hash::make($data['password']),
'email_token' => base64_encode($data['email']),
]);
Auth::loginUsingId($user->id);
}
}
User Model
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use App\Jobs\SendEmailJob;
class User extends Authenticatable implements MustVerifyEmail
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'email','name','password','username','picture',
'ip_address','email_verified_at','email_token','verified'
];
/**
* 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',
];
function socialProviders(){
return $this->hasMany(socialProvider::class);
}
// This is the code define in the sendEmailVerificationNotification
public function sendEmailVerificationNotification()
{
SendEmailJob::dispatch($this);
}
}
You have overwritten the registration logic, but you have ignored the fact that create method needs to return an instance of App\User - or at least a class that implements Authenticatable.
Take a look at the original logic; you will see that the docblock shows that an instance of App\User is being returned and that the original implementation returns the result of the User::create() call.
To get your custom method working, update it like so:
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'username' => slugify($data['name'])."-".mt_rand(10000, 99999);,
'email' => $data['email'],
'password' => Hash::make($data['password']),
'email_token' => base64_encode($data['email']),
]);
}
Laravel will take care of logging the user in by default anyway.
I have table comments with column parent_id.
And this is content of CommentsTable.php:
namespace App\Model\Table;
use App\Model\Entity\Comment;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
/**
* Comments Model
*/
class CommentsTable extends Table
{
/**
* Initialize method
*
* #param array $config The configuration for the Table.
* #return void
*/
public function initialize(array $config)
{
$this->table('comments');
$this->displayField('id');
$this->primaryKey('id');
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Posts', [
'foreignKey' => 'post_id',
'joinType' => 'INNER'
]);
$this->belongsTo('ParentComments', [
'className' => 'Comments',
'foreignKey' => 'parent_id'
]);
$this->hasMany('ChildComments', [
'className' => 'Comments',
'foreignKey' => 'parent_id'
]);
}
/**
* Default validation rules.
*
* #param \Cake\Validation\Validator $validator Validator instance.
* #return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator)
{
$validator
->add('id', 'valid', ['rule' => 'numeric'])
->allowEmpty('id', 'create')
->requirePresence('body', 'create')
->notEmpty('body')
->requirePresence('path', 'create')
->notEmpty('path')
->add('status', 'valid', ['rule' => 'numeric'])
->requirePresence('status', 'create')
->notEmpty('status')
->add('created_at', 'valid', ['rule' => 'datetime'])
->requirePresence('created_at', 'create')
->notEmpty('created_at')
->add('updated_at', 'valid', ['rule' => 'datetime'])
->requirePresence('updated_at', 'create')
->notEmpty('updated_at');
return $validator;
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* #param \Cake\ORM\RulesChecker $rules The rules object to be modified.
* #return \Cake\ORM\RulesChecker
*/
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->existsIn(['user_id'], 'Users'));
$rules->add($rules->existsIn(['post_id'], 'Posts'));
$rules->add($rules->existsIn(['parent_id'], 'ParentComments'));
return $rules;
}
}
I want to build rule for field parent_id: exist in ParentComments or equal to 0.
Can you help me?
Thank you very much.
Rules are just callable functions or callable classes. The existsIn() function is just an alias for the ExistsIn class. We can use the to our advantage:
...
use Cake\ORM\Rule\ExistsIn;
class CommentsTable extends Table
{
...
public function buildRules(RulesChecker $rules)
{
...
$rules->add(
function ($entity, $options) {
$rule = new ExistsIn(['parent_id'], 'ParentComments');
return $entity->parent_id === 1 || $rule($entity, $options);
},
['errorField' => 'parent_id', 'message' => 'Wrong Parent']
);
return $rules;
}
}