I was recently updating from laravel's sanctum to passport; and there is this one test that bothers me a lot.
In sanctum there is this method under the PersonalAccessToken model that finds the token and returns the token if it exists.
I don't seem to find anything like that in the docs or online.
I'm validating the test by asserting that $user->tokens is not empty... yet I wish to validate that the token I'm returning from my login controller is indeed a token; not just the creation;
Thnx in advance...
Login Test
public function user_can_login()
{
//$this->withoutExceptionHandling();
$user = User::factory()->create();
$url = route('api.v1.auth.login', [
'email' => $user->email,
'password' => 'password'
]);
$res = $this->jsonApi()
->post($url)
->assertStatus(200);
$token = $res->json(['access_token']);
$this->assertNotEmpty($user->tokens);
}
Login method in authcontroller
public function login(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
$credentials = $request->only(['email', 'password']);
if (Auth::attempt($credentials)) {
$user = Auth::user();
$access_token = $user->createToken('laravel-api.local')->accessToken;
return response()->json(['access_token' => $access_token], 200);
} else {
return response()->json(['error' => 'Unauthorized'], 401);
}
}
pues:dont know why im writing the code, but just for ref of what i'm doing
https://laracasts.com/discuss/channels/testing/how-do-i-create-a-route-while-testing
solution is quite simple... you'll find it here... I had an issue when I tried that before hand and it seems to be with the use of the Route::name('name') method and the route('name') function threw a server error. but if you call the path directly it should work...
any who... authController and login method stay the same but the test changes to...
public function setUp(): void
{
parent::setUp();
Route::middleware('auth:api')
->get('/test-route', function (Request $request) {
return $request->user();
});
$clientRepository = new ClientRepository();
$client = $clientRepository->createPersonalAccessClient(
null,
'Personal Access Client Test',
'/'
);
DB::table('oauth_personal_access_clients')->insert([
'client_id' => $client->id,
'created_at' => date('Y-m-d'),
'updated_at' => date('Y-m-d'),
]);
}
/** #test */
public function user_can_login_with_correct_credentials()
{
//$this->withoutExceptionHandling();
$user = User::factory()->create();
$url = route('api.v1.auth.login', [
'email' => $user->email,
'password' => 'password',
'device_name' => $user->name . ' test Device'
]);
$res = $this->jsonApi()
->post($url)
->assertStatus(200);
$token = $res->json(['access_token']);
$this->jsonApi()
->withHeader('Authorization', 'Bearer ' . $token)
->get('/test-route')
->assertStatus(200);
}
Related
I try make rest API with Laravel 8 + Sanctum. And my database is MySql Maria DB.
I create LoginController and make function call login. When i try my API, it's always return Unauthorized. I pretty sure my USERNAME and PASSWORD is correct.
This is my LoginController
public function store(Request $request) {
$user = User::create(
[
"USERNAME" => $request->username,
"PASSWORD" => Hash::make($request->password),
"ADM_MST_SITE_ID" => 0,
]
);
$token = $user->createToken('apiToken')->plainTextToken;
$res = [
'user' => $user,
'token' => $token
];
return response($res, 201);
}
public function login(Request $request)
{
$data = $request->validate([
'username' => 'required|string',
'password' => 'required|string'
]);
$user = User::where('username', $data['username'])->first();
$credentials = request(['username', 'password']);
if(!Auth::attempt($credentials))
return response()->json([
'message' => 'Unauthorized'
], 401);
$token = $user->createToken('apiToken')->plainTextToken;
$res = [
'user' => $user,
'token' => $token
];
return response($res, 201);
}
Model
////
protected $table = 'adm_mst_user';
protected $guarded = ['ID'];
public function getAuthPassword()
{
return $this->PASSWORD;
}
////
The store function is work well, the new data are inserted to my database. But, when i login with username and password, it's not working.
I try 2 different auth check, using Auth::attempt and Hash::check.
I don't know where the error coming from. It's always return Unauthorized.
$user = User::where('username', $data['username'])->first();
$this->guard()->login($user);
and make a guard function in same controller
protected function guard()
{
return Auth::guard();
}
import use Illuminate\Support\Facades\Auth; in top
include
use Illuminate\Support\Facades\Hash;
You need to make it with email not with username
$credentials = request(['email', 'password']);
OR, modify your attempt code
if(!Auth::attempt(['username' => $credentials['username'], 'password' => $credentials['password']))
this code worked with sanctum
use App\Models\User;
use Illuminate\Support\Facades\Hash;
function login($candidate)
{
$user = User::where('username', $candidate['username'])->first();
if (!$user || !Hash::check($candidate['password'], $user->password)) {
return [
'message' => 'These credentials do not match our records.'
];
}
$token = $user->createToken('my-token')->plainTextToken;
return [
'user' => $user,
'token' => $token
];
}
I am trying to register a new user into my system, and right after make the login automatically. How can I call another function in the same Controller and pass $request variables to it?
I did the var_dump, login function is getting data, the login is being made, but it's not redirecting to index (line 28)
public function login(Request $request)
{
//var_dump($request->only('email', 'password'));
$credentials = [
'email' => $request->email,
'password' => $request->password,
];
if(Auth::attempt($credentials)) {
return redirect()->route('movie.index');
}
return redirect()->route('login')->with([
'error' => 'danger',
'msg' => 'Error message',
]);
}
public function register(Request $request)
{
$newUser = new User;
$newUser->name = $request->name;
$newUser->email = $request->email;
$newUser->password = Hash::make($request->password);
$newUser->save();
$this->login($request);
}
Right way is
Auth::login($newUser);
Then redirect to your page after login.
I want to implement Passport authentication in Laravel. this is the register function:
public function register(Request $request)
{
$credentials = $request->only('name', 'email', 'password');
$rules = [
'name' => 'required|max:100',
'email' => 'required|email|max:120|unique:users',
'password' => 'required',
];
$validator = Validator::make($credentials, $rules);
if($validator->fails()) {
return response()->json(['success'=> false, 'error'=> $validator->errors()]);
}
$user = User::create(['name' => $request->name, 'email' => $request->email, 'password' => bcrypt($request->password)]);
if(Auth::attempt($credentials)){
$user = Auth::guard('api')->user();
$data['id'] = $user->id;
$data['name'] = $user->name;
$data['phone'] = $user->phone;
$data['token'] = $user->createToken('API')->accessToken;
return response()->json([
'success'=> true,
'data'=> $data
]);
}
return response()->json([
'success'=> false,
'data'=> $response
]);
}
and this is my routes:
Route::post('register', 'Api\AuthController#register');
Route::middleware('auth:api')->get('/user', function (Request $request) {
return response()->json($request->user());
});
I want to display the user information in postman, and this is the request header to the url: http://127.0.0.1:8004/api/user:
Accept:application/json
Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiOThjYjM0YjkzOWJhMzczMDEwMGI0NmEyNTBhOGEzYTc5MTAyMjI1M2E2OTM0OGY0NGU1YWU4Njg3MzZkYmVlZjNlNzI1MDNiZTRhMjE5NGUiLCJpYXQiOjE1ODQ1NDczMDcsIm5iZiI6MTU4NDU0NzMwNywiZXhwIjoxNjE2MDgzMzA3LCJzdWIiOiI1NyIsInNjb3BlcyI6W119.GcqelFT2d3kKi8fR2vNbgMB1Fe_sQjrd2Mb3cRQLbS20IR_445bcTbcl17yKJrldboFktobeSIHx1GQENIzQbO0RStysmisiKuLk8eoXUvNVJq3t1bpZrjPBiNEGDRPqezq5VEsGhotVgbKRLK1gbVHwvE7mtSuGQTp9nIf6PEsmiJLsGmUJ0GdCmWXXLvJ0dBac1DZ_KauppDs_Lymx9SEXgzTDW60rpYrwHNbbaLfa6wdW3M5tUZM3vMRcKhCgYitvK_DfttKHcWqvEX8_lZT0h5GcQSsori_K8Lj_ynKfjrTfbodUKzT4kDZ8z-RnE4-SgG75LWDeqcpDRhuDmiL0KTIzwtrNFtU0NEo-v0t6dTkAuJCl1ZnTT72sLZoI6rsTPHtNKIDxwN9VrXiTU5pxGEc6ju5e30NQnkjBRjMRsVIcCHR-WohObuWkZOGRq-RP5on3oiLe2VGk0PENXXziMX3D5urpLWK3WR-ZY0Bz3fKitgE8TFaT1cOMSyK6d3zskUEdMjDyLCxbS7vKhmNuAy2moOj7f7DI9yr8XNeyF00WJKw0WJi76XX_Y06O-VtNhqzgeEyu6QM6qRivpBBcj-WkdbSTmveNZlSqAesLm6WD8qWKc9FR-S_41fCc2qLEY_VOotSA8tOYASVKpdsvj2liTbbMH9905HQJe-o
Content-Type:application/json
but the result is always:
{
"message": "Unauthenticated."
}
How could I display user information? thanks in advance
Change
Auth::attempt($credentials)
to
Auth::guard('api')->attempt($credentials)
I made a RegistrationRequest and a LoginRequest and when I register the user I login the user immediatly. But when I try to pass the RegistrationRequest into my LoginRequest I get the following error
Can you not pass requests on to other functions? I did it with normal requests and that worked fine, but I gues the are of the same type.
public function login(LoginRequest $request)
{
$credentials = $request->only('email', 'password');
if ($token = $this->guard()->attempt($credentials))
return $this->respondWithToken($token);
return response()->json(['error' => 'Unauthorized'], 401);
}
public function register(RegistrationRequest $request)
{
$user = User::create([
'user_name' => $request->user_name,
'first_name' => $request->first_name,
'last_name' => $request->last_name,
'email' => $request,
]);
return response()->json([
'success' => true,
'data' => $user,
'meta' => $this->login($request),
], 200);
}
I try to create custom login page but I got an error
Undefined index: password
my controller code
$this->validate($Request, [
'Email' => 'required',
'password' => 'required',
]);
$email = $Request['Email'];
$password = md5($Request['password']);
$login = new login();
$login = login::where('Email', $email);
if(empty($password))
{
return('404');
}
if(Auth::attempt(['Email' => $Request->input('Email'), 'Password' =>$password]))
{
return ('ok');
}
return ('no');
any one help my to create custom login
this is my new code
but again i gor undefined::passsword
public function logincheck(Request $request)
{
$this->validate($request, [
'Email' => 'required',
'password' => 'required',
]);
$email = $request->Email;
$password = md5($request->get('password'));
if(Auth::attempt(['Email' => $request->get('Email'), 'Password' =>md5($request->get('password'))]))
{
return ('ok');
}
return ('no');
}
Your error comes from
$Request['password']
You are treating Request as an array. It's an object. You do
public funciton login(Request $request)
{
$password = $request->password;
//or use the global helper
$password = request('password');
//Attempt login
if(Auth::attempt(['Email' => $request->get('Email'), 'Password' =>$password]))
{
return ('ok');
}
}
Also if you follow Laravel tutorial properly, you don't need md5 to hash password. Auth::attemp() will hash it for you