How to make login as other user in API using laravel passport? - laravel

I am using laravel passport for API authentication. and I want to log in as different users with different roles from superadmin. So how can I achieve this? Please give your suggestions.
public function masqueradeNotary($profileId)
{
$userId = decodeC($profileId);
$notaryUser = $this->adminService->getUser($userId);
if($userId){
//logout from current login user
$user = auth()->user()->token();
$user->revoke();
//login as notary user
$userRoles = $notaryUser->roles()->get();
// $scopes = [];
// if ($userRoles) {
// $scopes = Arr::pluck($userRoles,'code');
// }
if(Auth::login($notaryUser)){
\Log::info("auth user");
\Log::info(auth()->user());
// $token = $user->createToken($user->email . '-' . now(), $scopes);
}
}
}

Welcome to stackoverflow.
Well, you should look at spatie's package, it might make your life easier.
You can apply roles on the registration if you create two different registration functions. In the front-end, you have to somehow make the user decide and pass that value (a checkbox would be ideal).

I got the solution. there is no need to check auth login just log out the current user and revoke the access token and create a token for the user directly.
$token = $user->createToken($user->email . '-' . now(), $scopes);

Related

How can I add ask username and password feature to only one of my laravel routes?

I have created a few forms in laravel. I want to restrict access to one of them only to a specific user.
I want to create a user and password myself.
This is my routes excerpt. This is the route I want to protect from access
Route::get('/tabledata_id_title', 'KedivimController#appearanceiddata');
This is my controller excerpt:
public function appearanceiddata()
{
//$magic = DB::table('prog_title')->select('pr_id', 'pr_title')->get();
$magic = DB::table('prog_title')->select('pr_id', 'pr_title')-> where('pr_index', '=', 1)->get();
return view ('takealook', ['magical' => $magic]);
}
This is a short fix for your problem.
public function appearanceiddata()
{
if (!Auth::guard('web')->check()) //check if someone is logged in
{
//redirect to login page.
}
else {
/*Check if the logged in user is your desired user.
Maybe try matching the logged in id with your desired id.
If you find that a user is logged in but they are not your desired user
then you may redirect them in some other place or show them a message. */
}
//$magic = DB::table('prog_title')->select('pr_id', 'pr_title')->get();
$magic = DB::table('prog_title')->select('pr_id', 'pr_title')-> where('pr_index', '=', 1)->get();
return view ('takealook', ['magical' => $magic]);
}
However, this practice is ok if you have one or two restricted field. But if you have more than that then you should read about middleware.

Laravel Personal Access Tokens

Is there a way to re-view the accessToken itself after it's been created?
Looking at the code below you can see that $token holds the accessToken for the "Test Token" client and that's fine it works as expected, however, say the user forgot that $token is there a way to display it for the user again?
// user can manually create personal access token
// by using the following
$user = Auth::user();
$token = $user->createToken('Test Token')->accessToken;
// this works fine, however, I want to allow the user to edit / re-view these personal access
// tokens when he/she wants
// I'm able to delete or revoke these tokens but how can I vew the access token again?
// I tried the following:
foreach (Auth::user()->tokens as $token)
{
// but none of these give back that access token??
// halp!
// print "accessToken: " . $token->accessToken;
// print "token: " . $token->token;
}
If I understood correctly: you can store the tokens in DB. If there is more tokens per user you can store it in json format.

How to Get facebook friendlist in laravel

how to get facebook friendlist in laravel when user login by facebook login. Already I get the name, email. But I want frienlist also. Here is my existing code.
public function redirectToProvider()
{
return Socialite::driver('facebook')->redirect();
}
public function handleProviderCallback()
{
$socialize_user = Socialite::driver('facebook')->user();
$facebook_user_id = $socialize_user->getId(); // unique facebook user id
$facebook_name = $socialize_user->getName();
$facebook_email = $socialize_user->getEmail();
$facebook_image = $socialize_user->getAvatar();
$user = Register::where('facebook_id', $facebook_user_id)->first();
if ($user) {
Session::put('id',$user->id);
Session::put('name',$user->name);
return redirect::to('welcome');
}
// register (if no user)
if (!$user) {
$user = new Register;
$user->facebook_id = $facebook_user_id;
$user->name = $facebook_name;
$user->email = $facebook_email;
$user->image = $facebook_image;
$user->save();
return redirect('welcome');
}
}
Before anything you will need the user permission, even if they have already signed in
Short version:
You can't with only socialite or without adding few classes.
Long version:
You need to extend FacebookProvider and implement the user interface.
This is the user interface of the user so you can add the friend list method.
And this is the FacebookProvider which includes the required authentication for accessing the facebook state and token, you can read on the loginFlow process on facebook.
To get access to the user friend list, you need to get the user permission, hence you need to initiate the full process again and add the user permission or add it at the start of the process.
Quick version:
If it is only for the friend list, better to use JavaScript and add friend list permission, and then use the response that you get, facebook graph api JS.
Laravel version:
check this package from sammyK it gives you great control on FacebookPHPSDK if you want more functions.

Do I need to store the FB access token on the backend in my Laravel Socialite+JWT and Ionic app?

I am slightly confused about the correct flow to Register and Login a user with cordova-plugin-facebook4 and Laravel Socialite + tymondesigns/jwt-auth. My front end is in Ionic 2 and the backend is in Laravel 5.4
My flow: (heavily borrowed from this blog post)
Using the cordova-plugin-facebook4 , perform a FB.login(). This returns the following json
{
status: "connected",
authResponse: {
session_key: true,
accessToken: "EAACgZAhHOaPsBAIjUUASeKSLnbEkashdkashdkhakdhakdh",
expiresIn: 5183979,
sig: "...",
secret: "...",
userID: "634565435"
}
}
Post the "accessToken" to http:///auth/facebook
Retrieve the user profile using the Socialite "userFromToken" method.
$profile = Socialite::driver('facebook')->userFromToken($token);
Check if the user exists in the DB.
IF it does create and return a new access token using JWTAuth
ELSE create a new user in the DB and return a new access token using JWTAuth
$provider = "facebook"
try{
$profile = Socialite::driver($provider)->userFromToken($token);
}
catch(Exception $exception)
{
return response()->json([
'error'=>'User retrieval failed from provider'
],401);
}
//Check if the user registered earlier with this provider.
try{
$existingUser = User::where('provider','=',$provider)
->where('provider_id','=',$profile->getId())
->firstOrFail();
//If user is found and no exception was raised
if ($existingUser)
{
return response()->json([
'token'=>JWTAuth::fromUser($existingUser),
'user'=>$existingUser
]);
}
}
catch (ModelNotFoundException $exception)
{
$user=new User();
$user->email=$profile->getEmail();
$user->name=$profile->getName();
$user->password=$this->random_password();
$user->provider=$provider;
$user->provider_id=$profile->getId();
$user->save();
return response()->json([
'token'=>JWTAuth::fromUser($user),
'user'=>$user
]);
}
My Confusion:
Are the "Login with Facebook" and "Register/Signup with Facebook" two exclusive functions? How would subsequent logins work for a mobile app after the user registers on Laravel the first time?
In Step 4 when I check if the user exists in the backend I'm querying the table on the "provider_id" returned by Socialite::driver($provider)->userFromToken($token)->getId(). I don't understand how this value is unique to a particular user.
In both cases for step 2 - a new JWT Auth token is created from the user and returned to the front end. I plan to save this token on the front end and use it for protected resource access. However, I'm not sure if I need to store the FB Access_Token in the DB and share it with the front end to be cached as well.
How will the login process work when the app is reopened. The user should be auto logged in but would this happen via Facebook, via Laravel Social or just the locally stored JWT?
Thanks
Sam

Using laravel socialite and jwt-auth without session

Short version: What would be the appropriate way to send the JWT generated from Facebook login (laravel/socialite) to the angularjs front end without using session.
Long Version
I am making an app that has angularjs front end and laravel 5.2 backend. I am using tymondesigns/jwt-auth for authentication instead of session.
I am also using laravel/socialite for social Facebook authentication. For that I am using the stateless feature of socialite so that I don't need session in any ways.
The basic authentication works perfectly. But, when I try to use Facebook login, I follow these steps
User clicks on a button on the angular side that redirects to the provider login page of the back end.
public function redirectToProvider() {
return Socialite::with('facebook')->stateless()->redirect();
}
2. User gives his login information. After logging in he is redirected to my handlecallback function.
try {
$provider = Socialite::with('facebook');
if ($request->has('code')) {
$user = $provider->stateless()->user();
}
} catch (Exception $e) {
return redirect('auth/facebook');
}
return $this->findOrCreateUser($user);
Next I use the findorcreate function to determine whether the user exists or not. If not than I just create a new user and create JWT from that.
$user = User::where('social_id', '=', $facebookUser->id)->first();
if (is_object($user)) {
$token = JWTAuth::fromUser($user);
return redirect()->to('http://localhost:9000/#/profile?' . 'token=' . $token);#angular
} else {
$result = array();
$result['name'] = $facebookUser->user['first_name']
$result['email'] = $facebookUser->user['email'];
$result['social_id'] = $facebookUser->id;
$result['avatar'] = $facebookUser->avatar;
$result['gender'] = $facebookUser->user['gender'];
$result['status'] = 'active';
$result['login_type'] = 'facebook';
$result['user_type'] = 'free_user';
try {
$user = User::create($result);
} catch (Exception $e) {
return response()->json(['error' => 'User already exists.'], HttpResponse::HTTP_CONFLICT);
}
$token = JWTAuth::fromUser($user);
return redirect()->to('http://localhost:9000/#/profile?' . 'token=' . $token);#angular
}
My problem is, in the last block of code I am having to send the jwt to my frontend via url. Which isn't secure at all. What would be the right way to send the generated JWT to the frontend without using session. Thank you
The official documentation of Laravel Socialite says:
Stateless Authentication
The stateless method may be used to disable session state verification. This is useful when adding social authentication to an API:
return Socialite::driver('google')->stateless()->user();
Then, you can authenticate using the jwt-auth method:
JWTAuth::fromUser($user)
If you're using $http on the Angular side, try returning the token as a JSON response from Laravel:
return response()->json(compact('token'));
Then store the token in localStorage or sessionStorage or what have you.
If you're generating your Angular page from within Laravel (i.e. not using Laravel as an API, but showing your Angular page from /public/index.php, for instance) you could load the view with the token in the data for the view.
As long as you're using HTTPS either of these two scenarios are better than passing the token in the redirect URL.
You can store token and use client side redirect without storing to browser history to redirect user to profile page without token in URL:
document.location.replace({profile-url})

Resources