I have an issue with authenticating a user. This is the Authentication method in my controller:
public function authenticate(Request $request){
$user = User::where('username', $request->username)->first();
$user_model = new User;
$return_credentials = [
'message' => "User does not exist.",
'status' => false,
'user_details' => ""
];
if(!empty($user) && !is_null($user)){
$remember = Str::random(60);
if(\Auth::attempt(['username' => $request->username, 'password' => $request->password, 'verified' => '1'], $remember)){
$user = \Auth::user();
$token_result = $user->createToken('Personal Access Token');
$token = $token_result->token;
$token->expires_at = Carbon::now()->addWeeks(1);
$return_credentials['message'] = "User Successfully Logged in.";
$return_credentials['status'] = true;
$token->save();
}else{
$return_credentials['message'] = "User Failed to Log in.";
$return_credentials['status'] = false;
}
}
$return_credentials['user_details'] = $user;
return response()->json($return_credentials);
}
Every time I access a route using(this middleware):
Route::group(['middleware' => 'auth:api'], function() {
Route::get('user', '\App\Http\Controllers\UserController#verifyUserLoggedIn');
});
It returns:
GET http://..../api/auth/user 401 (Unauthorized)
Q: Am I missing a step or anything?
Add auth:api in your app\Http\kernel.php :
'api' => [
'throttle:60,1',
'bindings',
'auth:api',
],
Related
I am using the latest version of Laravel Sanctum to create a validation method for my SPA, but I ran into an issue(notice that I dont work that long with laravel). When I login it works, but when I logout and try to login it stops working. After some testing I noticed that this was because of a cookie that was added by laravel.
// loginController
public function login(Request $request)
{
if ($this->validator($request->all())->fails()) {
//validation stuff
} else {
$credentials = [
'email' => $request->email,
'password' => $request->password,
];
$user = User::where('email', $request->email)->firstOrFail();
if (auth()->attempt($credentials)) {
$token = $user->createToken('auth')->plainTextToken;
$response_code = 200;
$response = [
'user' => $user,
'success' => true,
'errors' => false,
'message' => 'Login successfully',
'access_token' => $token,
'token_type' => 'Bearer',
];
} else {
$response_code = 422;
$response = [
'success' => false,
'errors' => [],
'message' => 'Invalid login'
];
}
}
public function logout(Request $request)
{
$request->user()->tokens()->delete();
}
I get the following error when logging in with my mobile phone:
Uncaught (in promise) Error: Request failed with status code 422
how can i fix this?
My Controller
public function login(Request $request)
{
$req = Request::create(route('passport.token'), 'POST', [
//'grant_type' => 'password',
'client_id' => 2,
'client_secret' => '326g3KM3giN4o3UHITByxPLHaZlWzqfZbWs0vWLd',
'phone_number' => $request->phone_number,
//'password' => $request->password,
]);
$response = app()->handle($req);
if ($response->status() == 400) {
return response()->json([
'message' => ''
]);
} else if ($response->status() == 401) {
return response()->json([
'message' => ''
]);
}
return $response;
I also redefined functions in the user model
public function findForPassport($identifier) {
return $this->where('phone_number', $identifier)->first();
}
public function validateForPassportPasswordGrant($password)
{
return true;
}
I've read your description. So, you have to store phone and code in the table users. To simplify it, you can store code in DB field password as an encrypted value.
$user->phone_number = $request->phone_number;
$user->password = bcrypt($code);
And then during login you can use your own code:
$req = Request::create(route('passport.token'), 'POST', [
'grant_type' => 'password',
'client_id' => 2,
'client_secret' => '326g3KM3giN4o3UHITByxPLHaZlWzqfZbWs0vWLd',
'phone_number' => $request->phone_number,
'password' => $request->code,
]);
$response = app()->handle($req);
I use passport in my laravel project to authenticate users by api. API work correctly on my local host. But after i deploy it on Plesk server token doesnt create. Always show Server Error.
public function login(Request $request) {
$validator = Validator::make($request->all(),[
'email' => 'required',
'password' => 'required',
]);
if($validator->fails()) {
return response()->json(["validation errors" => $validator->errors()]);
}
$email = $request->email;
$password = $request->password;
error_log($password);
$user = DB::table("users")->where([["email", "=", $email]])->first();
if(is_null($user)) {
return response()->json(["success" => false, "message" => "User doesn't exist"]);
}
if(Auth::attempt(['email' => request('email'), 'password' => request('password')])) {
$user = Auth::user();
$token = $user->createToken('token')->accessToken;
$success['success'] = true;
$success['user'] = $user;
$success['message'] = "Success! you are logged in successfully";
$success['token'] = $token;
return response()->json(['success' => $success ], 200);
} else {
return response()->json(['error' => 'Unauthorised'], 401);
}
}
$token = $user->createToken('token')->accessToken;
This line throw error
Problem was in my AuthServiceProvider
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
'Medicare\Model' => 'Medicare\Policies\ModelPolicy',
];
public function boot()
{
$this->registerPolicies();
Passport::routes();
//
}
}
After i commented 'Medicare\Model' => 'Medicare\Policies\ModelPolicy' everything works fine.
I am trying to make an API with Passport. If a user tries to login or signs up with Socialite, find user than generate access_token then redirect to the frontend with access_token in URL parameters.
I tried to register and login than generate access_token with user email and the default password, which is not suitable for security.
try {
$serviceUser = Socialite::driver($service)->stateless()->user();
} catch (\Exception $e) {
return redirect(config('app.client_url').'/auth/social-callback?error=Unable to login using '.$service.'. Please try again'.'&origin=login');
}
$email = $serviceUser->getEmail();
$name = $serviceUser->getName();
$user = $this->getExistingUser($serviceUser, $email, $service);
$newUser = false;
if (!$user) {
$newUser = true;
$user = new User;
$user->name = $name;
$user->email = $email;
$user->username = Str::random(10);
if ($service === 'facebook') {
$user->image = $serviceUser->avatar;
}
$user->verify = true;
$user->save();
}
if ($this->needsToCreateSocial($user, $service)) {
Social::create([
'user_id' => $user->id,
'social_id' => $serviceUser->getId(),
'service' => $service
]);
}
$http = new Client;
$response = $http->post(config('app.url').'/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => '2',
'client_secret' => 'oBKWxgF2fDvrxwA05ciapwy4JYKaHxzhGzr6D24X',
'username' => $email,
'password' => 'gebdandi',
'scope' => '',
],
]);
$body = json_decode((string) $response->getBody(), true);
$accessToken = $body['access_token'];
return redirect(config('app.client_url').'/social-callback?token='.$accessToken.'&origin='.($newUser ? 'register' : 'login'));
I can't find any solution in the documentation.
after reading all documentation i found solution in this documentation
i did like this
edit authserviceprovider like this
public function boot()
{
$this->registerPolicies();
Passport::routes();
Passport::personalAccessClientId(1);
Passport::tokensExpireIn(now()->addDays(15));
Passport::refreshTokensExpireIn(now()->addDays(30));
}
added code in controller like this
$accessToken = $user->createToken('access_token')->accessToken;
thanks for laravel Team for provide good documentation
I am trying to generate a bearer token with access and refresh tokens after user authenticates with socialite.
public function handleProviderCallback($provider, EmailConfirmationMailer $mailer)
{
$user = Socialite::driver($provider)->user();
if(User::where('email', '=', $user->getEmail())->exists()){
$exist_user = User::where('email', '=', $user->getEmail())->first();
Auth::loginUsingId($exist_user->id);
$http = new GuzzleHttp\Client;
$response = $http->post('http://localhost:8000/oauth/token', [
'form_params' => [
'grant_type' => 'refresh_token',
'refresh_token' => 'the-refresh-token',
'client_id' => 1,
'client_secret' => 'c4ojSmOjl04QrshdSXlOmbKUOIxm6zqyhND34AT0',
'scope' => '',
],
]);
return json_decode((string) $response->getBody(), true);
}else{
//create new user here
}
}
I got the error from vendor\laravel\socialite\src\Two\AbstractProvider.php
user function, message is "".
public function user()
{
if ($this->hasInvalidState()) {
throw new InvalidStateException;//here is the highlighted
}
$response = $this->getAccessTokenResponse($this->getCode());
$user = $this->mapUserToObject($this->getUserByToken(
$token = Arr::get($response, 'access_token')
));
return $user->setToken($token)
->setRefreshToken(Arr::get($response, 'refresh_token'))
->setExpiresIn(Arr::get($response, 'expires_in'));
}
What is the best practice for this situation? Any help is greatly appreciated.
resorted to generate accessToken with no refreshToken:
public function handleProviderCallback($provider)
{
$user = Socialite::driver($provider)->user();
if(User::where('email', '=', $user->getEmail())->exists()){
$existUser = User::where('email', '=', $user->getEmail())->first();
Auth::login($existUser,true);
//remove existing tokens from user
$tokenResult = $existUser->createToken('Personal Access Token');
return \response()->json([
'token_type' => 'Bearer',
'expires_in' => $tokenResult->token->expires_at->diffInSeconds(Carbon::now()),
'access_token' => $tokenResult->accessToken,
'info' => 'Existing user'
]);
}else{
//create new user entry
}
}